"use strict"; exports.tzOffset = tzOffset; const offsetFormatCache = {}; const offsetCache = {}; /** * The function extracts UTC offset in minutes from the given date in specified * time zone. * * Unlike `Date.prototype.getTimezoneOffset`, this function returns the value * mirrored to the sign of the offset in the time zone. For Asia/Singapore * (UTC+8), `tzOffset` returns 480, while `getTimezoneOffset` returns -480. * * @param timeZone - Time zone name (IANA or UTC offset) * @param date - Date to check the offset for * * @returns UTC offset in minutes */ function tzOffset(timeZone, date) { try { const format = offsetFormatCache[timeZone] ||= new Intl.DateTimeFormat("en-GB", { timeZone, hour: "numeric", timeZoneName: "longOffset" }).format; const offsetStr = format(date).split('GMT')[1] || ''; if (offsetStr in offsetCache) return offsetCache[offsetStr]; return calcOffset(offsetStr, offsetStr.split(":")); } catch { // Fallback to manual parsing if the runtime doesn't support ±HH:MM/±HHMM/±HH // See: https://github.com/nodejs/node/issues/53419 if (timeZone in offsetCache) return offsetCache[timeZone]; const captures = timeZone?.match(offsetRe); if (captures) return calcOffset(timeZone, captures.slice(1)); return NaN; } } const offsetRe = /([+-]\d\d):?(\d\d)?/; function calcOffset(cacheStr, values) { const hours = +values[0]; const minutes = +(values[1] || 0); return offsetCache[cacheStr] = hours > 0 ? hours * 60 + minutes : hours * 60 - minutes; }