Skip to content

Commit 55867aa

Browse files
committed
Check whether date is valid in getDayOfWeekFromYmd helper
1 parent e174021 commit 55867aa

6 files changed

+57
-36
lines changed

src/datetime/_formatDateIso.ts

+2-29
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,3 @@
1-
import { formatExactTimeIso } from "./_formatExactTimeIso.js";
2-
3-
export function formatDateIso(date: Date) {
4-
const year = date.getFullYear();
5-
const month = date.getMonth() + 1;
6-
const day = date.getDate();
7-
const hour = date.getHours();
8-
const minute = date.getMinutes();
9-
const second = date.getSeconds();
10-
const millisecond = date.getMilliseconds();
11-
12-
const offset = date.getTimezoneOffset();
13-
14-
const offsetHours = Math.floor(Math.abs(offset) / 60)
15-
.toString()
16-
.padStart(2, "0");
17-
const offsetMinutes = (Math.abs(offset) % 60).toString().padStart(2, "0");
18-
const offsetString = `${offset > 0 ? "-" : "+"}${offsetHours}:${offsetMinutes}`;
19-
20-
return formatExactTimeIso(
21-
year,
22-
month,
23-
day,
24-
hour,
25-
minute,
26-
second,
27-
millisecond,
28-
offsetString,
29-
);
1+
export function formatDateIso(year: number, month: number, day: number) {
2+
return `${year.toString()}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}`;
303
}

src/datetime/_formatExactTimeIso.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { formatDateIso } from "./_formatDateIso.js";
2+
13
export function formatExactTimeIso(
24
year: number,
35
month: number,
@@ -8,12 +10,9 @@ export function formatExactTimeIso(
810
millisecond: number,
911
offsetString: string,
1012
) {
11-
const yearStr = year.toString();
12-
const monthStr = month.toString().padStart(2, "0");
13-
const dayStr = day.toString().padStart(2, "0");
1413
const hourStr = hour.toString().padStart(2, "0");
1514
const minuteStr = minute.toString().padStart(2, "0");
1615
const secondStr = second.toString().padStart(2, "0");
1716
const millisecondStr = millisecond.toString().padStart(3, "0");
18-
return `${yearStr}-${monthStr}-${dayStr}T${hourStr}:${minuteStr}:${secondStr}.${millisecondStr}${offsetString}`;
17+
return `${formatDateIso(year, month, day)}T${hourStr}:${minuteStr}:${secondStr}.${millisecondStr}${offsetString}`;
1918
}
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { formatExactTimeIso } from "./_formatExactTimeIso.js";
2+
3+
export function formatIsoFromDateObject(date: Date) {
4+
const year = date.getFullYear();
5+
const month = date.getMonth() + 1;
6+
const day = date.getDate();
7+
const hour = date.getHours();
8+
const minute = date.getMinutes();
9+
const second = date.getSeconds();
10+
const millisecond = date.getMilliseconds();
11+
12+
const offset = date.getTimezoneOffset();
13+
14+
const offsetHours = Math.floor(Math.abs(offset) / 60)
15+
.toString()
16+
.padStart(2, "0");
17+
const offsetMinutes = (Math.abs(offset) % 60).toString().padStart(2, "0");
18+
const offsetString = `${offset > 0 ? "-" : "+"}${offsetHours}:${offsetMinutes}`;
19+
20+
return formatExactTimeIso(
21+
year,
22+
month,
23+
day,
24+
hour,
25+
minute,
26+
second,
27+
millisecond,
28+
offsetString,
29+
);
30+
}

src/datetime/_getDayOfWeekFromYmd.test.ts

+9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ test("result of getDayOfWeekFromYmd should match to Temporal's dayOfWeek", () =>
2222
);
2323
});
2424

25+
test("invalid date", () => {
26+
expect(() => {
27+
getDayOfWeekFromYmd(2024, 1, 366);
28+
}).toThrowError();
29+
expect(() => {
30+
getDayOfWeekFromYmd(2023, 2, 29);
31+
}).toThrowError();
32+
});
33+
2534
test("getDayOfWeekFromYmd with a day which doesn't exist in local time zone", () => {
2635
zoneModifier.set("Pacific/Apia");
2736
// 2011/12/30 was skipped in Pacific/Apia due to offset change (UTC-11:00 -> UTC+13:00)

src/datetime/_getDayOfWeekFromYmd.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
1+
import { formatDateIso } from "./_formatDateIso.js";
2+
13
/**
24
* same as temporal's spec, Monday: 1, Tuesday: 2, ... Sunday: 7
35
*/
46
export function getDayOfWeekFromYmd(year: number, month: number, day: number) {
5-
return ((new Date(Date.UTC(year, month - 1, day)).getUTCDay() + 6) % 7) + 1;
7+
const date = new Date(Date.UTC(year, month - 1, day));
8+
if (
9+
date.getUTCFullYear() !== year ||
10+
date.getUTCMonth() !== month - 1 ||
11+
date.getUTCDate() !== day
12+
) {
13+
throw new Error(`Invalid date: ${formatDateIso(year, month, day)}`);
14+
}
15+
return ((date.getUTCDay() + 6) % 7) + 1;
616
}

src/datetime/toTemporalFromClockTime.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Temporal } from "../types.js";
2-
import { formatDateIso } from "./_formatDateIso.js";
2+
import { formatIsoFromDateObject } from "./_formatIsoFromDateObject.js";
33

44
/**
55
* Returns Temporal instance which represents clock (local) time of given date.
@@ -18,6 +18,6 @@ export function toTemporalFromClockTime<
1818
date: Date,
1919
TemporalClass: TemporalClassType,
2020
): InstanceType<TemporalClassType> {
21-
const dateIso = formatDateIso(date);
21+
const dateIso = formatIsoFromDateObject(date);
2222
return TemporalClass.from(dateIso) as InstanceType<TemporalClassType>;
2323
}

0 commit comments

Comments
 (0)