PronounsPage/composables/useTimezone.ts
2024-10-15 14:14:41 +02:00

73 lines
2.1 KiB
TypeScript

import { DateTime, IANAZone } from 'luxon';
const CONTINENT_ICONS: Record<string, string> = {
Africa: 'globe-africa',
America: 'globe-americas',
Antarctica: 'globe',
Arctic: 'globe',
Asia: 'globe-asia',
Atlantic: 'globe-americas',
Australia: 'globe-asia',
Europe: 'globe-europe',
Indian: 'globe-asia',
Pacific: 'globe-asia',
};
const timezoneOverrides: Record<string, string> = {
'Europe/Kiev': 'Europe/Kyiv',
};
export interface TimezoneInfo {
timezone: string;
area: string;
location: string;
displayLocation: string;
icon: string;
offset: number;
offsetFormatted: string;
short: string;
long: string;
}
export default () => {
const detectBrowserTimezone = (): string => {
return DateTime.local().zone.name;
};
const getTimezoneInfo = (timezone: string | null): TimezoneInfo | null => {
if (!timezone) {
return null;
}
const parts = timezone.split('/');
const displayParts = timezoneDisplayName(timezone).split('/');
const area = parts[0];
const location = parts[parts.length - 1].replace(/_/g, ' ');
const displayLocation = displayParts[parts.length - 1].replace(/_/g, ' ');
const tz = new IANAZone(timezone);
if (!tz.isValid) {
return null;
}
const dt = DateTime.local().setZone(tz);
return {
timezone,
area,
location,
displayLocation,
icon: CONTINENT_ICONS[area],
offset: dt.offset,
// @ts-expect-error: DateTime.ts: number not in typings but in code (probably version mismatch)
offsetFormatted: tz.formatOffset(dt.ts, 'short'),
short: dt.offsetNameShort,
long: dt.offsetNameLong,
};
};
const timezoneDisplayName = (timezone: string): string => {
return (timezoneOverrides[timezone] || timezone).replaceAll('_', ' ');
};
return {
detectBrowserTimezone,
getTimezoneInfo,
timezoneDisplayName,
};
};