mirror of
https://github.com/langgenius/dify.git
synced 2026-11-11 22:02:23 +08:00
61 lines
2.3 KiB
TypeScript
61 lines
2.3 KiB
TypeScript
import tz from './timezone.json'
|
|
|
|
type Item = {
|
|
value: string
|
|
name: string
|
|
}
|
|
export const timezones: Item[] = tz
|
|
|
|
export const getBrowserTimezone = () => {
|
|
if (typeof Intl === 'undefined') return undefined
|
|
|
|
return new Intl.DateTimeFormat().resolvedOptions().timeZone || undefined
|
|
}
|
|
|
|
const DEFAULT_OFFSET_STR = 'UTC+0'
|
|
|
|
const formatOffset = (totalMinutes: number) => {
|
|
const sign = totalMinutes >= 0 ? '+' : '-'
|
|
const absMinutes = Math.abs(totalMinutes)
|
|
const hours = Math.floor(absMinutes / 60)
|
|
const minutes = absMinutes % 60
|
|
return minutes !== 0
|
|
? `UTC${sign}${hours}:${String(minutes).padStart(2, '0')}`
|
|
: `UTC${sign}${hours}`
|
|
}
|
|
|
|
// Offset in minutes of a timezone at a given instant, following DST. Undefined if the runtime cannot resolve it.
|
|
export const getTimezoneOffsetMinutes = (timezone: string, date: Date): number | undefined => {
|
|
try {
|
|
const name = new Intl.DateTimeFormat('en-US', {
|
|
timeZone: timezone,
|
|
timeZoneName: 'longOffset',
|
|
})
|
|
.formatToParts(date)
|
|
.find((part) => part.type === 'timeZoneName')?.value
|
|
if (name === 'GMT') return 0
|
|
const match = name ? /^GMT([+-])(\d{2}):(\d{2})$/.exec(name) : null
|
|
if (!match) return undefined
|
|
const totalMinutes = Number(match[2]) * 60 + Number(match[3])
|
|
return match[1] === '-' ? -totalMinutes : totalMinutes
|
|
} catch {
|
|
return undefined
|
|
}
|
|
}
|
|
|
|
export const convertTimezoneToOffsetStr = (timezone?: string, date: Date = new Date()) => {
|
|
if (!timezone) return DEFAULT_OFFSET_STR
|
|
const offsetMinutes = getTimezoneOffsetMinutes(timezone, date)
|
|
if (offsetMinutes !== undefined) return formatOffset(offsetMinutes)
|
|
const tzItem = tz.find((item) => item.value === timezone)
|
|
if (!tzItem) return DEFAULT_OFFSET_STR
|
|
// Fallback for runtimes without the timezone. Extract the standard offset from names like "-11:00 Niue Time".
|
|
const offsetMatch = /^([+-]?\d{1,2}):(\d{2})/.exec(tzItem.name)
|
|
/* v8 ignore next 2 -- timezone.json entries are normalized to "{offset} {name}"; this protects against malformed data only. */
|
|
if (!offsetMatch) return DEFAULT_OFFSET_STR
|
|
const hours = Number.parseInt(offsetMatch[1]!, 10)
|
|
const minutes = Number.parseInt(offsetMatch[2]!, 10)
|
|
const sign = hours >= 0 ? '+' : ''
|
|
return minutes !== 0 ? `UTC${sign}${hours}:${offsetMatch[2]}` : `UTC${sign}${hours}`
|
|
}
|