feat: infer default time format from navigator.language
This commit is contained in:
parent
f89b8c3b52
commit
e55ffccd21
3 changed files with 53 additions and 3 deletions
|
|
@ -8,6 +8,7 @@ import {
|
|||
formatShortDateTime,
|
||||
formatTime,
|
||||
formatTimeAgo,
|
||||
inferDateTimePreferences,
|
||||
} from "../datetime";
|
||||
|
||||
afterEach(() => {
|
||||
|
|
@ -89,6 +90,14 @@ describe("datetime formatters", () => {
|
|||
expect(formatTime(sampleDate, { locale: "en-US", timeZone: "UTC", timeFormat })).toBe(expected);
|
||||
});
|
||||
|
||||
test.each([
|
||||
["en-US", { dateFormat: "MM/DD/YYYY", timeFormat: "12h" }],
|
||||
["en-GB", { dateFormat: "DD/MM/YYYY", timeFormat: "24h" }],
|
||||
["ja-JP", { dateFormat: "YYYY/MM/DD", timeFormat: "24h" }],
|
||||
] as const)("infers date and time preferences for %s", (locale, expected) => {
|
||||
expect(inferDateTimePreferences(locale)).toEqual(expected);
|
||||
});
|
||||
|
||||
test("formats combined values with custom date and time preferences", () => {
|
||||
expect(
|
||||
formatDateTime(sampleDate, {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ export const TIME_FORMATS = ["12h", "24h"] as const;
|
|||
export type TimeFormatPreference = (typeof TIME_FORMATS)[number];
|
||||
export const DEFAULT_TIME_FORMAT: TimeFormatPreference = "12h";
|
||||
|
||||
const BROWSER_PREFERENCE_SAMPLE_DATE = new Date(Date.UTC(2006, 0, 2, 15, 4, 5));
|
||||
|
||||
const DATE_PART_ORDERS = {
|
||||
"MM/DD/YYYY": ["month", "day", "year"],
|
||||
"DD/MM/YYYY": ["day", "month", "year"],
|
||||
|
|
@ -109,6 +111,43 @@ function formatConfiguredTime(date: Date, options: DateFormatOptions) {
|
|||
}).format(date);
|
||||
}
|
||||
|
||||
export function inferDateTimePreferences(locale?: string) {
|
||||
const dateOrder = getDateTimeFormat(locale, undefined, {
|
||||
month: "numeric",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
})
|
||||
.formatToParts(BROWSER_PREFERENCE_SAMPLE_DATE)
|
||||
.flatMap((part) => {
|
||||
if (part.type === "year" || part.type === "month" || part.type === "day") {
|
||||
return [part.type];
|
||||
}
|
||||
|
||||
return [];
|
||||
})
|
||||
.join("/");
|
||||
|
||||
let dateFormat = DEFAULT_DATE_FORMAT;
|
||||
|
||||
if (dateOrder === "day/month/year") {
|
||||
dateFormat = "DD/MM/YYYY";
|
||||
} else if (dateOrder === "year/month/day") {
|
||||
dateFormat = "YYYY/MM/DD";
|
||||
}
|
||||
|
||||
let timeFormat: TimeFormatPreference = "12h";
|
||||
const hour12 = getDateTimeFormat(locale, undefined, { hour: "numeric" }).resolvedOptions().hour12;
|
||||
|
||||
if (hour12 === false) {
|
||||
timeFormat = "24h";
|
||||
}
|
||||
|
||||
return {
|
||||
dateFormat,
|
||||
timeFormat,
|
||||
};
|
||||
}
|
||||
|
||||
// 1/10/2026, 2:30 PM
|
||||
export function formatDateTime(date: DateInput, options: DateFormatOptions = {}): string {
|
||||
return formatValidDate(
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import { useState } from "react";
|
|||
import { useNavigate } from "@tanstack/react-router";
|
||||
import { normalizeUsername } from "~/lib/username";
|
||||
import { z } from "zod";
|
||||
import { DEFAULT_DATE_FORMAT, DEFAULT_TIME_FORMAT } from "~/client/lib/datetime";
|
||||
import { inferDateTimePreferences } from "~/client/lib/datetime";
|
||||
|
||||
export const clientMiddleware = [authMiddleware];
|
||||
|
||||
|
|
@ -59,10 +59,12 @@ export function OnboardingPage() {
|
|||
return;
|
||||
}
|
||||
|
||||
const { dateFormat, timeFormat } = inferDateTimePreferences(navigator.language);
|
||||
|
||||
const { data, error } = await authClient.signUp.email({
|
||||
username: normalizeUsername(values.username),
|
||||
dateFormat: DEFAULT_DATE_FORMAT,
|
||||
timeFormat: DEFAULT_TIME_FORMAT,
|
||||
dateFormat,
|
||||
timeFormat,
|
||||
password: values.password,
|
||||
email: values.email.toLowerCase().trim(),
|
||||
name: values.username,
|
||||
|
|
|
|||
Loading…
Reference in a new issue