vremel
Version:
JavaScript date utility library for Temporal API
97 lines (93 loc) • 2.76 kB
text/typescript
import {
isInstantConstructor,
isZonedDateTimeConstructor,
} from "../type-utils.js";
import type { Temporal } from "../types.js";
import { formatExactTimeIso } from "./_formatExactTimeIso.js";
import { getDayOfWeekFromYmd } from "./_getDayOfWeekFromYmd.js";
import { getDayOfWeekNumberFromAbbreviation } from "./_getDayOfWeekNumberFromAbbreviation.js";
import { getMonthNumberFromAbbreviation } from "./_getMonthNumberFromAbbreviation.js";
const regex =
/^([A-Za-z]{3}), (\d\d) ([A-Za-z]{3}) (\d{4}) (\d\d):(\d\d):(\d\d) GMT$/;
function parse(
date: string,
): [
year: number,
month: number,
day: number,
hour: number,
minute: number,
second: number,
] {
const result = regex.exec(date);
if (result === null) {
throw new Error("Invalid format");
}
const [, dayOfWeek, day, monthName, year, hour, minute, second] = result;
if (
dayOfWeek === undefined ||
day === undefined ||
monthName === undefined ||
year === undefined ||
hour === undefined ||
minute === undefined ||
second === undefined
) {
throw new Error("something wrong");
}
const y = parseInt(year);
const m = getMonthNumberFromAbbreviation(monthName);
const d = parseInt(day);
const weekNum = getDayOfWeekNumberFromAbbreviation(dayOfWeek);
if (getDayOfWeekFromYmd(y, m, d) !== weekNum) {
throw new Error(`Wrong day of week: ${dayOfWeek}`);
}
return [y, m, d, parseInt(hour), parseInt(minute), parseInt(second)];
}
/**
* Creates Temporal object from datetime string in RFC 7231's format (HTTP date format)
* such as `Mon, 01 Jan 2024 01:23:45 GMT`.
* This function doesn't support obsoleted formats.
*
* @param date datetime string in RFC 7231's format
* @param TemporalClass Temporal class (such as `Temporal.PlainDateTime` or `Temporal.Instant`) which will be returned
* @returns an instance of Temporal class specified in `TemporalClass` argument
*/
export function fromRfc7231<
TemporalClassType extends
| typeof Temporal.Instant
| typeof Temporal.ZonedDateTime
| typeof Temporal.PlainDateTime,
>(
date: string,
TemporalClass: TemporalClassType,
): InstanceType<TemporalClassType> {
const result = parse(date);
const [year, month, day, hour, minute, second] = result;
if (isInstantConstructor(TemporalClass)) {
return TemporalClass.from(
formatExactTimeIso(year, month, day, hour, minute, second, 0, "Z"),
) as InstanceType<TemporalClassType>;
}
if (isZonedDateTimeConstructor(TemporalClass)) {
return TemporalClass.from({
year,
month,
day,
hour,
minute,
second,
calendarId: "iso8601",
timeZone: "UTC",
}) as InstanceType<TemporalClassType>;
}
return TemporalClass.from({
year,
month,
day,
hour,
minute,
second,
calendarId: "iso8601",
}) as InstanceType<TemporalClassType>;
}