fix: respect time format preference in UI
Add shared time formatting helpers that apply the Appearance time format preference consistently. Update visible time labels across chat, quota usage, scheduled tasks, tunnels, context details, git views, PR metadata, and passkey settings to use the selected 12-hour, 24-hour, or automatic format. Leave date-only and non-UI formatting untouched so unrelated behavior does not change.
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
import { formatDateTimeForPreference, formatTimeForPreference } from '@/lib/timeFormat';
|
||||
import type { TimeFormatPreference } from '@/stores/useUIStore';
|
||||
|
||||
export const clampPercent = (value: number | null): number | null => {
|
||||
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
||||
return null;
|
||||
@@ -22,6 +25,7 @@ export const formatQuotaValueLabel = (
|
||||
export const formatQuotaResetLabel = (
|
||||
resetAt: number | null,
|
||||
fallback?: string | null,
|
||||
timeFormatPreference: TimeFormatPreference = 'auto',
|
||||
): string => {
|
||||
if (!resetAt) {
|
||||
return fallback ?? '';
|
||||
@@ -37,13 +41,10 @@ export const formatQuotaResetLabel = (
|
||||
const isToday = resetDate.toDateString() === now.toDateString();
|
||||
|
||||
if (isToday) {
|
||||
return resetDate.toLocaleTimeString(undefined, {
|
||||
hour: 'numeric',
|
||||
minute: '2-digit',
|
||||
});
|
||||
return formatTimeForPreference(resetDate, timeFormatPreference, { fallback: fallback ?? '' });
|
||||
}
|
||||
|
||||
return resetDate.toLocaleString(undefined, {
|
||||
return formatDateTimeForPreference(resetDate, timeFormatPreference, {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
weekday: 'short',
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import type { TimeFormatPreference } from '@/stores/useUIStore';
|
||||
|
||||
type TimePrecision = 'minute' | 'second';
|
||||
|
||||
const getHour12Option = (preference: TimeFormatPreference): boolean | undefined => {
|
||||
if (preference === '12h') return true;
|
||||
if (preference === '24h') return false;
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const getUses24HourForPreference = (preference: TimeFormatPreference, locale: string): boolean => {
|
||||
if (preference === '24h') return true;
|
||||
if (preference === '12h') return false;
|
||||
|
||||
try {
|
||||
const options = new Intl.DateTimeFormat(locale, { hour: 'numeric' }).resolvedOptions();
|
||||
if (typeof options.hour12 === 'boolean') {
|
||||
return !options.hour12;
|
||||
}
|
||||
return options.hourCycle === 'h23' || options.hourCycle === 'h24';
|
||||
} catch {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
export const formatTimeForPreference = (
|
||||
timestamp: number | Date,
|
||||
preference: TimeFormatPreference,
|
||||
options: { precision?: TimePrecision; hour?: 'numeric' | '2-digit'; fallback?: string } = {},
|
||||
): string => {
|
||||
const date = timestamp instanceof Date ? timestamp : new Date(timestamp);
|
||||
if (!Number.isFinite(date.getTime())) {
|
||||
return options.fallback ?? '';
|
||||
}
|
||||
|
||||
return date.toLocaleTimeString(undefined, {
|
||||
hour: options.hour ?? 'numeric',
|
||||
minute: '2-digit',
|
||||
second: options.precision === 'second' ? '2-digit' : undefined,
|
||||
hour12: getHour12Option(preference),
|
||||
});
|
||||
};
|
||||
|
||||
export const formatDateTimeForPreference = (
|
||||
timestamp: number | Date,
|
||||
preference: TimeFormatPreference,
|
||||
options: Intl.DateTimeFormatOptions,
|
||||
): string => {
|
||||
const date = timestamp instanceof Date ? timestamp : new Date(timestamp);
|
||||
if (!Number.isFinite(date.getTime())) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return date.toLocaleString(undefined, {
|
||||
...options,
|
||||
hour12: options.hour ? getHour12Option(preference) : options.hour12,
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user