@burglekitt/gmt
Version:
Temporal-based date and time utilities with timezone support and polyfill integration
78 lines (77 loc) • 3.37 kB
JavaScript
import { Temporal } from "@js-temporal/polyfill";
import { getWeekNumber } from "../../plain/calculate/getWeekNumber.js";
import { getSystemTimeZone } from "../../zoned/get/index.js";
import { convertUnixToZoned } from "../convert/index.js";
import { isValidUnixMilliseconds, isValidUnixSeconds, } from "../validate/index.js";
/**
* Extract a unit from a unix epoch value.
*
* - Valid units: "year", "month", "week", "day", "dayOfWeek", "hour", "minute", "second", "millisecond", "microsecond", "nanosecond".
* - Converts to ZonedDateTime then extracts the unit.
* - Returns "" for invalid input.
*
* @param value unix epoch in milliseconds or seconds (number or string)
* @param unit unit to extract (e.g. "year", "month", "hour")
* @param options optional: epochUnit ("seconds" | "milliseconds"), timeZone (IANA), weekStartsOn ("monday" | "sunday")
* @returns extracted unit value as string, or "" on invalid input
*
* @example parseUnitFromUnix(1700000000000, "year") // "2023"
* @example parseUnitFromUnix(1700000000, "hour", { epochUnit: "seconds" }) // "12"
* @example parseUnitFromUnix(1704067200000, "week") // "1"
* @example parseUnitFromUnix(1704067200000, "week", { weekStartsOn: "sunday" }) // "1"
* @example parseUnitFromUnix(-86400, { epochUnit: "seconds" }, "year") // "1969"
*/
export function parseUnitFromUnix(value, unit, options) {
const numValue = typeof value === "string" ? Number(value) : value;
const epochUnit = options?.epochUnit ?? "milliseconds";
if (epochUnit === "seconds") {
if (!isValidUnixSeconds(numValue))
return "";
}
else {
if (!isValidUnixMilliseconds(numValue))
return "";
}
const timeZone = options?.timeZone ?? getSystemTimeZone();
if (!timeZone)
return "";
const zoned = typeof options?.epochUnit === "undefined"
? convertUnixToZoned(numValue, timeZone)
: convertUnixToZoned(numValue, timeZone, options.epochUnit);
if (!zoned)
return "";
const weekStartsOn = options?.weekStartsOn ?? "monday";
try {
const zdt = Temporal.ZonedDateTime.from(zoned);
switch (unit) {
case "year":
return zdt.year.toString();
case "month":
return zdt.month.toString().padStart(2, "0");
case "week": {
return (getWeekNumber(`${zdt.year}-${zdt.month.toString().padStart(2, "0")}-${zdt.day.toString().padStart(2, "0")}`, weekStartsOn) ?? 0).toString();
}
case "day":
return zdt.day.toString().padStart(2, "0");
case "dayOfWeek":
return zdt.dayOfWeek.toString();
case "hour":
return zdt.hour.toString().padStart(2, "0");
case "minute":
return zdt.minute.toString().padStart(2, "0");
case "second":
return zdt.second.toString().padStart(2, "0");
case "millisecond":
return zdt.millisecond.toString().padStart(3, "0");
case "microsecond":
return (zdt.microsecond ?? 0).toString().padStart(3, "0");
case "nanosecond":
return (zdt.nanosecond ?? 0).toString().padStart(9, "0");
default:
return "";
}
}
catch {
return "";
}
}