frigate/web/src/hooks/use-date-utils.ts
Josh Hawkins b6e0e5698a
Proper i18n date/time handling (#17858)
* install date-fns-tz

* add date locale hook

* refactor formatUnixTimestampToDateTime

Use date-fns style instead of using strftime. This requires changing the i18n keys to the way date-fns represents dates (eg: "MMM d, h:mm:ss aaa"  instead of "%b %-d, %H:%M"

* refactor calendar to use new hook

* fix useFormattedTimestamp to use new formatUnixTimestampToDateTime date_format

* change i18n keys to new format

* fix timeline

* fix review

* fix explore

* fix metrics

* fix notifications

* fix face library

* clean up
2025-04-22 15:50:21 -06:00

100 lines
2.4 KiB
TypeScript

import { FrigateConfig } from "@/types/frigateConfig";
import { formatUnixTimestampToDateTime } from "@/utils/dateUtil";
import { useMemo } from "react";
import { useDateLocale } from "@/hooks/use-date-locale";
export function useFormattedTimestamp(
timestamp: number,
format: string,
timezone?: string,
) {
const locale = useDateLocale();
const formattedTimestamp = useMemo(() => {
return formatUnixTimestampToDateTime(timestamp, {
timezone,
date_format: format,
locale,
});
}, [format, timestamp, timezone, locale]);
return formattedTimestamp;
}
export function useFormattedRange(start: number, end: number, format: string) {
const locale = useDateLocale();
const formattedStart = useMemo(() => {
return formatUnixTimestampToDateTime(start, {
date_format: format,
locale,
});
}, [format, start, locale]);
const formattedEnd = useMemo(() => {
return formatUnixTimestampToDateTime(end, {
date_format: format,
locale,
});
}, [format, end, locale]);
return `${formattedStart} - ${formattedEnd}`;
}
export function useTimezone(config: FrigateConfig | undefined) {
return useMemo(() => {
if (!config) {
return undefined;
}
return (
config.ui?.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone
);
}, [config]);
}
export function use24HourTime(config: FrigateConfig | undefined) {
const localeUses24HourTime = useMemo(
() =>
new Intl.DateTimeFormat(undefined, {
hour: "numeric",
})
?.formatToParts(new Date(2020, 0, 1, 13))
?.find((part) => part.type === "hour")?.value?.length === 2,
[],
);
return useMemo(() => {
if (!config) {
return false;
}
if (config.ui.time_format !== "browser") {
return config.ui.time_format === "24hour";
}
return localeUses24HourTime;
}, [config, localeUses24HourTime]);
}
export function useFormattedHour(
config: FrigateConfig | undefined,
time: string, // hour is assumed to be in 24 hour format per the Date object
) {
const hour24 = use24HourTime(config);
return useMemo(() => {
if (hour24) {
return time;
}
const [hour, minute] = time.includes(":") ? time.split(":") : [time, "00"];
const hourNum = parseInt(hour);
const adjustedHour = hourNum % 12 || 12;
const period = hourNum < 12 ? "AM" : "PM";
return `${adjustedHour}:${minute} ${period}`;
}, [hour24, time]);
}