import {HOUR, MINUTE} from './units.js'; const offset = /^(?:GMT|UTC)(?:(\+|\-)([0-9]{2}):([0-9]{2}))?$/; export interface TimeZone { id: string; getOffsetMillisecondsFor(instant: number): number; } const timeZones = new Map(); export class DateTimeFormatTimeZone implements TimeZone { dateFormat: Intl.DateTimeFormat; constructor(public id: string) { this.dateFormat = new Intl.DateTimeFormat('en-US', { timeZoneName: 'longOffset', minute: 'numeric', timeZone: id, }); } getOffsetMillisecondsFor(milliseconds: number): number { let timeZonePart = this.dateFormat.formatToParts(new Date(milliseconds)).find(part => part.type === 'timeZoneName'); if (timeZonePart) { let result = timeZonePart.value.match(offset); if (result) { let sign = result[1]; let minute = result[2]; let second = result[3]; if (sign != null) { let multiplier = sign === '-' ? -1 : 1; return (parseInt(minute, 10) * HOUR + parseInt(second, 10) * MINUTE) * multiplier; } return 0; } } throw new RangeError('Invalid offset for instant'); } static from(name: string) { let timeZone = timeZones.get(name); if (!timeZone) { timeZone = new DateTimeFormatTimeZone(name); timeZones.set(name, timeZone); } return timeZone; } }