Skip to content

Commit 8a0e09b

Browse files
VIA-629 SB Add datetime parser.
1 parent b105f07 commit 8a0e09b

File tree

2 files changed

+132
-25
lines changed

2 files changed

+132
-25
lines changed

src/utils/date.test.ts

Lines changed: 119 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,133 @@
1-
import { UtcDateFromStringSchema } from "@src/utils/date";
1+
import { UtcDateFromStringSchema, UtcDateTimeFromStringSchema } from "@src/utils/date";
22

3-
describe("UtcDateFromStringSchema", () => {
4-
it("should parse winter date", () => {
5-
const actual = UtcDateFromStringSchema.parse("2026-01-01");
3+
describe("utils-date", () => {
4+
describe("UtcDateFromStringSchema", () => {
5+
it("should parse winter date", () => {
6+
const actual = UtcDateFromStringSchema.parse("2026-01-01");
67

7-
expect(actual).toEqual(new Date("2026-01-01"));
8-
});
8+
expect(actual).toEqual(new Date("2026-01-01"));
9+
});
910

10-
it("should parse summer date", () => {
11-
const actual = UtcDateFromStringSchema.parse("2026-06-01");
11+
it("should parse summer date", () => {
12+
const actual = UtcDateFromStringSchema.parse("2026-06-01");
1213

13-
expect(actual).toEqual(new Date("2026-06-01"));
14-
});
14+
expect(actual).toEqual(new Date("2026-06-01"));
15+
});
16+
17+
it("should throw on invalid date", () => {
18+
const given = "2026-13-01";
19+
20+
expect(() => {
21+
UtcDateFromStringSchema.parse(given);
22+
}).toThrow();
23+
});
1524

16-
it("should throw on invalid date", () => {
17-
const given = "2026-13-01";
25+
it("should throw on date without dashes", () => {
26+
const given = "20261301";
1827

19-
expect(() => {
20-
UtcDateFromStringSchema.parse(given);
21-
}).toThrow();
28+
expect(() => {
29+
UtcDateFromStringSchema.parse(given);
30+
}).toThrow();
31+
});
32+
33+
it("should throw on badly formed date", () => {
34+
const given = "Sausages";
35+
36+
expect(() => {
37+
UtcDateFromStringSchema.parse(given);
38+
}).toThrow();
39+
});
2240
});
2341

24-
it("should throw on date without dashes", () => {
25-
const given = "20261301";
42+
describe("UtcDateTimeFromStringSchema with Zulu time", () => {
43+
it("should parse winter date", () => {
44+
const actual = UtcDateTimeFromStringSchema.parse("2026-01-01T13:16:02Z");
45+
46+
expect(actual).toEqual(new Date("2026-01-01T13:16:02.000Z"));
47+
});
48+
49+
it("should parse summer date", () => {
50+
const actual = UtcDateTimeFromStringSchema.parse("2026-06-01T13:16:02Z");
51+
52+
expect(actual).toEqual(new Date("2026-06-01T13:16:02.000Z"));
53+
});
54+
55+
it("should throw on invalid date", () => {
56+
const given = "2026-13-01T13:16:02Z";
57+
58+
expect(() => {
59+
UtcDateTimeFromStringSchema.parse(given);
60+
}).toThrow();
61+
});
62+
63+
it("should throw on invalid time", () => {
64+
const given = "2026-12-01T25:16:02Z";
65+
66+
expect(() => {
67+
UtcDateTimeFromStringSchema.parse(given);
68+
}).toThrow();
69+
});
2670

27-
expect(() => {
28-
UtcDateFromStringSchema.parse(given);
29-
}).toThrow();
71+
it("should throw on date without dashes", () => {
72+
const given = "20261301T13:16:02Z";
73+
74+
expect(() => {
75+
UtcDateTimeFromStringSchema.parse(given);
76+
}).toThrow();
77+
});
78+
79+
it("should throw on badly formed date", () => {
80+
const given = "SausagesT13:16:02Z";
81+
82+
expect(() => {
83+
UtcDateTimeFromStringSchema.parse(given);
84+
}).toThrow();
85+
});
3086
});
3187

32-
it("should throw on badly formed date", () => {
33-
const given = "Sausages";
88+
describe("UtcDateTimeFromStringSchema with offset time", () => {
89+
it("should parse winter date", () => {
90+
const actual = UtcDateTimeFromStringSchema.parse("2026-01-01T13:16:02+02:00");
91+
92+
expect(actual).toEqual(new Date("2026-01-01T11:16:02.000Z"));
93+
});
94+
95+
it("should parse summer date", () => {
96+
const actual = UtcDateTimeFromStringSchema.parse("2026-06-01T13:16:02+02:00");
97+
98+
expect(actual).toEqual(new Date("2026-06-01T11:16:02.000Z"));
99+
});
100+
101+
it("should throw on invalid date", () => {
102+
const given = "2026-13-01T13:16:02+02:00";
103+
104+
expect(() => {
105+
UtcDateTimeFromStringSchema.parse(given);
106+
}).toThrow();
107+
});
108+
109+
it("should throw on invalid time", () => {
110+
const given = "2026-12-01T25:16:02+02:00";
111+
112+
expect(() => {
113+
UtcDateTimeFromStringSchema.parse(given);
114+
}).toThrow();
115+
});
116+
117+
it("should throw on date without dashes", () => {
118+
const given = "20261301T13:16:02+02:00";
119+
120+
expect(() => {
121+
UtcDateTimeFromStringSchema.parse(given);
122+
}).toThrow();
123+
});
124+
125+
it("should throw on badly formed date", () => {
126+
const given = "SausagesT13:16:02+02:00";
34127

35-
expect(() => {
36-
UtcDateFromStringSchema.parse(given);
37-
}).toThrow();
128+
expect(() => {
129+
UtcDateTimeFromStringSchema.parse(given);
130+
}).toThrow();
131+
});
38132
});
39133
});

src/utils/date.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,16 @@ export const UtcDateFromStringSchema = z
1515
}
1616
return date;
1717
});
18+
19+
export const UtcDateTimeFromStringSchema = z.iso
20+
.datetime({ offset: true, message: "Invalid ISO 8601 datetime format" })
21+
.transform((str, ctx) => {
22+
const date = new Date(str);
23+
24+
if (isNaN(date.getTime())) {
25+
ctx.addIssue({ code: "custom", message: "Invalid date value" });
26+
return z.NEVER;
27+
}
28+
29+
return date;
30+
});

0 commit comments

Comments
 (0)