Skip to content

Commit 60359b9

Browse files
feat(date): add date time format
1 parent 9557b41 commit 60359b9

File tree

5 files changed

+108
-0
lines changed

5 files changed

+108
-0
lines changed

src/date/dateTimeFormat.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { describe, expect, test } from "bun:test"
2+
import {
3+
dateTimeFormat,
4+
formatDateTimeFull,
5+
formatDateTimeIso
6+
} from "./dateTimeFormat"
7+
import { dateTimeFormatStyle } from "./dateTimeFormatStyle"
8+
9+
describe("dateTimeFormat", () => {
10+
const testDate = new Date("2023-12-25T10:30:45.000Z")
11+
12+
test("formats date with iso format", () => {
13+
const result = dateTimeFormat(testDate, dateTimeFormatStyle.iso)
14+
expect(result).toBe("2023-12-25 10:30:45")
15+
})
16+
17+
test("formats date with full format", () => {
18+
const result = dateTimeFormat(testDate, dateTimeFormatStyle.full, "en-US")
19+
expect(result).toContain("December")
20+
expect(result).toContain("2023")
21+
expect(result).toContain("10:30")
22+
})
23+
24+
test("formats date time full", () => {
25+
const result = formatDateTimeFull(testDate, "en-US")
26+
expect(result).toContain("December")
27+
expect(result).toContain("2023")
28+
expect(result).toContain("10:30")
29+
})
30+
31+
test("formats date time iso", () => {
32+
const result = formatDateTimeIso(testDate)
33+
expect(result).toBe("2023-12-25 10:30:45")
34+
})
35+
36+
test("formats date time full with string input", () => {
37+
const result = formatDateTimeFull("2023-12-25T10:30:45.000Z", "en-US")
38+
expect(result).toContain("December")
39+
expect(result).toContain("2023")
40+
expect(result).toContain("10:30")
41+
})
42+
43+
test("formats date time iso with string input", () => {
44+
const result = formatDateTimeIso("2023-12-25T10:30:45.000Z")
45+
expect(result).toBe("2023-12-25 10:30:45")
46+
})
47+
})

src/date/dateTimeFormat.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { dateTimeFormatStyle, type DateTimeFormatStyle } from "~utils/date/dateTimeFormatStyle"
2+
import { dateTimeFormatterGetCached } from "./dateTimeFormatterGetCached"
3+
4+
export function dateTimeFormat(date: Date|string, format: DateTimeFormatStyle, l?: string) {
5+
const formatter = dateTimeFormatterGetCached(format, l)
6+
return formatter.format(typeof date === "string" ? new Date(date) : date)
7+
}
8+
9+
export function formatDateTimeFull(date: Date | string, l?: string) {
10+
return dateTimeFormat(typeof date === "string" ? new Date(date) : date, dateTimeFormatStyle.full, l)
11+
}
12+
13+
export function formatDateTimeIso(date: Date | string, l?: string) {
14+
return dateTimeFormat(typeof date === "string" ? new Date(date) : date, dateTimeFormatStyle.iso, l)
15+
}

src/date/dateTimeFormatStyle.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import * as v from "valibot"
2+
3+
export type DateTimeFormatStyle = keyof typeof dateTimeFormatStyle
4+
5+
export const dateTimeFormatStyle = {
6+
iso: "iso",
7+
full: "full",
8+
} as const
9+
10+
export const dateTimeFormatStyleSchema = v.enum(dateTimeFormatStyle)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { type DateTimeFormatStyle, dateTimeFormatStyle } from "~utils/date/dateTimeFormatStyle"
2+
3+
export function dateTimeFormatterCreate(format: DateTimeFormatStyle, l?: string): Intl.DateTimeFormat {
4+
if (format === dateTimeFormatStyle.iso) {
5+
return new Intl.DateTimeFormat("sv-SE", {
6+
// date
7+
year: "numeric",
8+
month: "numeric",
9+
day: "numeric",
10+
// time
11+
hour: "numeric",
12+
minute: "numeric",
13+
second: "numeric",
14+
// timeZoneName: "short",
15+
})
16+
}
17+
return new Intl.DateTimeFormat(l, {
18+
dateStyle: "full",
19+
timeStyle: "long",
20+
})
21+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { dateTimeFormatterCreate } from "~utils/date/dateTimeFormatterCreate"
2+
import { type DateTimeFormatStyle } from "./dateTimeFormatStyle"
3+
4+
let cachedLocale: string | undefined = undefined
5+
let cachedFormat: DateTimeFormatStyle | undefined = undefined
6+
let cachedFormatter: Intl.DateTimeFormat | undefined = undefined
7+
8+
export function dateTimeFormatterGetCached(format: DateTimeFormatStyle, l?: string): Intl.DateTimeFormat {
9+
if (!cachedFormatter || cachedLocale !== l || cachedFormat !== format) {
10+
cachedLocale = l
11+
cachedFormat = format
12+
cachedFormatter = dateTimeFormatterCreate(format, l)
13+
}
14+
return cachedFormatter
15+
}

0 commit comments

Comments
 (0)