From d47824c8f3bf7816da2ee6a75374fe4a2931f713 Mon Sep 17 00:00:00 2001 From: upstream Date: Fri, 2 Oct 2026 16:02:11 +0200 Subject: [PATCH] Upstream spencermountain/spacetime state of the touched files before fe90cae667 --- scripts/tz/update.js | 212 +++++ src/index.js | 68 ++ types/constructors.d.ts | 94 ++ zonefile/_build.js | 88 ++ zonefile/iana.js | 1897 +++++++++++++++++++++++++++++++++++++++ zonefile/pack.js | 47 + 6 files changed, 2406 insertions(+) create mode 100644 scripts/tz/update.js create mode 100644 src/index.js create mode 100644 types/constructors.d.ts create mode 100644 zonefile/_build.js create mode 100644 zonefile/iana.js create mode 100644 zonefile/pack.js diff --git a/scripts/tz/update.js b/scripts/tz/update.js new file mode 100644 index 0000000..8d89968 --- /dev/null +++ b/scripts/tz/update.js @@ -0,0 +1,212 @@ +// CLI orchestration: read zoneinfo, normalize records, report differences, then write. +import { execFileSync } from 'node:child_process' +import { + existsSync, + readFileSync, + readdirSync, + renameSync, + statSync, + unlinkSync, + writeFileSync +} from 'node:fs' +import { dirname, join, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' +import data from '../../zonefile/iana.js' +import aliases from '../../zonefile/aliases.js' +import { parseIntervals, normalizeZone } from './lib.js' +import { printHeader, printReport, printResult, printError, printHelp } from './report.js' + +const root = fileURLToPath(new URL('../../', import.meta.url)) +// Directory-only legacy keys may be retained with --allow-unsupported. +// Missing or malformed files remain fatal because their timezone state is unknown. +export class UnsupportedZoneError extends Error {} + +export const parseArgs = (args) => { + const options = { + year: new Date().getUTCFullYear(), + zoneinfoDir: '/usr/share/zoneinfo', + check: false, + verbose: false, + allowUnsupported: false + } + for (let i = 0; i < args.length; i += 1) { + const arg = args[i] + if (arg === '--check') { + options.check = true + } else if (arg === '--verbose') { + options.verbose = true + } else if (arg === '--allow-unsupported') { + options.allowUnsupported = true + } else if (arg === '--help') { + options.help = true + } else if (['--year', '--zoneinfo-dir', '--output'].includes(arg)) { + const value = args[++i] + if (!value || value.startsWith('--')) { + throw new Error('Missing value for ' + arg) + } + if (arg === '--year') { + if (!/^\d{4}$/.test(value) || Number(value) < 1900 || Number(value) > 9998) { + throw new Error('Year must be 1900–9998') + } + options.year = Number(value) + } else { + options[arg === '--output' ? 'output' : 'zoneinfoDir'] = resolve(value) + } + } else { + throw new Error('Unknown option: ' + arg) + } + } + options.output ||= join(root, `zonefile.${options.year}.js`) + return options +} + +// Library keys are lowercase; zoneinfo paths are case-sensitive on many systems. +// Apply known aliases, then resolve every component using its actual spelling. +export const resolveZone = (directory, name) => { + name = aliases[name] || name + let path = directory + for (const component of name.split('/')) { + if (!component || component === '.' || component === '..') { + throw new Error('Invalid zone name') + } + const matches = readdirSync(path).filter( + (entry) => entry.toLowerCase() === component.toLowerCase() + ) + if (matches.length !== 1) { + throw new Error('Missing or ambiguous zone: ' + name) + } + path = join(path, matches[0]) + } + const stats = statSync(path) + // zdump can silently report UTC for a directory. Reject it before invocation. + if (stats.isDirectory()) { + throw Object.assign(new UnsupportedZoneError('Zone name resolves to a directory, not a timezone: ' + name), { + details: [ + `Resolved path: ${path}`, + `Available entries: ${readdirSync(path).sort().join(', ')}`, + 'Choose a specific timezone or define an explicit library alias; a directory has no offset or transitions.' + ] + }) + } + if (!stats.isFile() || readFileSync(path).subarray(0, 4).toString() !== 'TZif') { + throw new Error('Not a compiled TZif file: ' + name) + } + return path +} + +// macOS provides +VERSION; common Linux distributions embed it in tzdata.zi. +// File modification times are not reliable tzdata release identifiers. +const sourceVersion = (directory) => { + for (const name of ['+VERSION', 'tzdata.zi']) { + const path = join(directory, name) + if (existsSync(path)) { + const text = readFileSync(path, 'utf8') + const version = name === '+VERSION' ? text.trim() : /^# version (\S+)/m.exec(text)?.[1] + if (version) { + return version + } + } + } + return 'unknown' +} + +// Inject the reader so callers can supply fixtures without invoking zdump. +// Build a fresh result and retain diagnostic context without mutating source data. +export const updateZones = (zones, year, readZone) => { + const result = {} + const changes = [] + const unsupported = [] + for (const [name, previous] of Object.entries(zones)) { + // Acquisition and parsing errors must fail, even with --allow-unsupported. + let intervals + try { + intervals = parseIntervals(readZone(name)) + } catch (error) { + if (error instanceof UnsupportedZoneError) { + unsupported.push({ name, reason: error.message, previous, details: error.details }) + result[name] = { ...previous } + continue + } + throw new Error(`${name}: ${error.message}`) + } + try { + result[name] = normalizeZone(intervals, previous, name, year) + } catch (error) { + unsupported.push({ name, reason: error.message, previous, intervals, details: error.details }) + result[name] = { ...previous } + continue + } + if (JSON.stringify(previous) !== JSON.stringify(result[name])) { + changes.push({ name, before: previous, after: result[name] }) + } + } + return { result, changes, unsupported } +} + +export const main = (args = process.argv.slice(2)) => { + const options = parseArgs(args) + if (options.help) { + printHelp() + return + } + const { year, zoneinfoDir } = options + const version = sourceVersion(zoneinfoDir) + const total = Object.keys(data).length + printHeader({ ...options, version, total }) + const { result, changes, unsupported } = updateZones(data, year, (name) => { + const path = resolveZone(zoneinfoDir, name) + // Bound extraction to one UTC year; argument arrays avoid shell interpretation. + // Interval output includes an initial offset even for zones with no transitions. + return execFileSync('zdump', ['-i', '-c', `${year},${year + 1}`, path], { + encoding: 'utf8', + timeout: 10000, + maxBuffer: 1024 * 1024, + env: { ...process.env, LC_ALL: 'C' }, + stdio: ['ignore', 'pipe', 'pipe'] + }) + }) + printReport({ changes, unsupported, total, verbose: options.verbose }) + // Check mode and the unsupported-zone gate must run before any file write. + if (options.check) { + if (changes.length > 0 || unsupported.length > 0) { + process.exitCode = 1 + } + printResult( + changes.length > 0 || unsupported.length > 0 ? 'Check needs attention. No files written.' : 'Check passed. No files written.', + Boolean(changes.length > 0 || unsupported.length > 0) + ) + return + } + if (unsupported.length > 0 && !options.allowUnsupported) { + throw new Error( + 'No output written. Resolve unsupported zones or explicitly preserve them with --allow-unsupported.' + ) + } + const source = JSON.stringify({ + year, + tzdata: version, + unsupported: unsupported.map((o) => o.name) + }) + const text = `// Generated by scripts/tz/update.js: ${source}\nexport default ${JSON.stringify(result, null, 2)}\n` + // Rename within the destination directory so readers never see a partial file. + // Only remove a temporary file created by this run (exclusive creation may fail). + const temporary = join(dirname(options.output), `.zonefile-${process.pid}.tmp`) + let created = false + try { + writeFileSync(temporary, text, { encoding: 'utf8', flag: 'wx' }) + created = true + renameSync(temporary, options.output) + } finally { + if (created && existsSync(temporary)) { + unlinkSync(temporary) + } + } + printResult(`Wrote ${options.output}`) +} + +try { + main() +} catch (error) { + printError(error.message) + process.exitCode = 1 +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..504609c --- /dev/null +++ b/src/index.js @@ -0,0 +1,68 @@ +import Spacetime from './spacetime.js' +import whereIts from './whereIts.js' +import version from './_version.js' + +const main = (input, tz, options) => new Spacetime(input, tz, options) + +// set all properties of a given 'today' object +const setToday = function (s) { + const today = s._today || {} + Object.keys(today).forEach((k) => { + s = s[k](today[k]) + }) + return s +} + +//some helper functions on the main method +main.now = (tz, options) => { + let s = new Spacetime(new Date().getTime(), tz, options) + s = setToday(s) + return s +} +main.today = (tz, options) => { + let s = new Spacetime(new Date().getTime(), tz, options) + s = setToday(s) + return s.startOf('day') +} +main.tomorrow = (tz, options) => { + let s = new Spacetime(new Date().getTime(), tz, options) + s = setToday(s) + return s.add(1, 'day').startOf('day') +} +main.yesterday = (tz, options) => { + let s = new Spacetime(new Date().getTime(), tz, options) + s = setToday(s) + return s.subtract(1, 'day').startOf('day') +} +main.fromUnixSeconds = (secs, tz, options) => { + return new Spacetime(secs * 1000, tz, options) +} + +main.extend = function (obj = {}) { + Object.keys(obj).forEach((k) => { + Spacetime.prototype[k] = obj[k] + }) + return this +} +main.timezones = function () { + const s = new Spacetime() + return s.timezones +} +main.max = function (tz, options) { + const s = new Spacetime(null, tz, options) + s.epoch = 8640000000000000 + return s +} +main.min = function (tz, options) { + const s = new Spacetime(null, tz, options) + s.epoch = -8640000000000000 + return s +} + +//find tz by time +main.whereIts = whereIts +main.version = version + +//aliases: +main.plugin = main.extend +export default main diff --git a/types/constructors.d.ts b/types/constructors.d.ts new file mode 100644 index 0000000..7baf2f2 --- /dev/null +++ b/types/constructors.d.ts @@ -0,0 +1,94 @@ +import type { Spacetime, ParsableDate, TimezoneSet } from './types.js' + +export interface SpacetimeConstructorOptions { + /** javascript dates use millisecond-epochs, instead of second-epochs, like some other languages. This is a common bug, and by default spacetime warns if you set an epoch within January 1970. to disable set to true */ + silent?: boolean + + /** the day number, between 0-6, that the week starts on. (Sunday is 0) */ + weekStart?: number + + /** pass true to change parsing behaviour to dd/mm/yyyy. By default American interpretation will be used. */ + dmy?: boolean +} + +export interface SpacetimeConstructor { + /** + * @param epoch Timestamp in **milliseconds**. If you are getting a date in 1970, you are likely using seconds. + * @param timezone Optional timezone. If omitted uses the browser timezone. + * @param options Options for silencing warnings. + */ + (epoch: number, timezone?: string, options?: SpacetimeConstructorOptions): Spacetime + + /** + * @param arr Date values in an array such as [yyyy, m, d]. + * + * ```typescript + * let d = spacetime([2011, 1, 15]); + * d.format('nice-year'); // "Feb 15th, 2011" + * ``` + * @param timezone Optional timezone. If omitted uses the browser timezone. + * @param options Options for silencing warnings. + */ + (arr: Array, timezone?: string, options?: SpacetimeConstructorOptions): Spacetime + + /** + * @param obj Date as a key-value object. ex {month:'june', year:2019} + * @param timezone Optional timezone. If omitted uses the browser timezone. + * @param options Options for silencing warnings. + */ + ( + obj: { [unit: string]: string | number }, + timezone?: string, + options?: SpacetimeConstructorOptions + ): Spacetime + + /** + * @param iso Date as an iso string. ex '2017-04-03T08:00:00' + * @param timezone Optional timezone. If omitted uses the browser timezone. + * @param options Options for silencing warnings. + */ + (iso: string, timezone?: string, options?: SpacetimeConstructorOptions): Spacetime + + /** + * @param parsableDate a parsable date like object + * @param timezone Optional timezone. If omitted uses the browser timezone. + * @param options Options for silencing warnings. + */ + ( + parsableDate?: ParsableDate | null, + timezone?: string, + options?: SpacetimeConstructorOptions + ): Spacetime +} + +export interface SpacetimeStatic extends SpacetimeConstructor { + /** set as the current time */ + now: (timezone?: string, options?: SpacetimeConstructorOptions) => Spacetime + + /** set as this morning */ + today: (timezone?: string, options?: SpacetimeConstructorOptions) => Spacetime + + /** set as tomorrow morning */ + tomorrow: (timezone?: string, options?: SpacetimeConstructorOptions) => Spacetime + + /** set as yesterday morning */ + yesterday: (timezone?: string, options?: SpacetimeConstructorOptions) => Spacetime + + /** set epoch using seconds instead of milliseconds */ + fromUnixSeconds: (seconds: number, timezone?: string, options?: SpacetimeConstructorOptions) => Spacetime + + /** Extend Spacetime with a custom function/object. */ + extend: (extension: { [key: string]: any } | {}) => SpacetimeStatic + + /** get a list of current timezones and their offsets */ + timezones: () => TimezoneSet + + /** list timezones by their time */ + whereIts: (a: string, b?: string) => string[] + + /** set as earliest-possible date */ + min: (timezone?: string, options?: SpacetimeConstructorOptions) => Spacetime + + /** set as furthest-possible future date */ + max: (timezone?: string, options?: SpacetimeConstructorOptions) => Spacetime +} diff --git a/zonefile/_build.js b/zonefile/_build.js new file mode 100644 index 0000000..86d49e2 --- /dev/null +++ b/zonefile/_build.js @@ -0,0 +1,88 @@ +export default { + "9|s": "2/dili,2/jayapura", + "9|n": "2/chita,2/khandyga,2/pyongyang,2/seoul,2/tokyo,2/yakutsk,11/palau,japan,rok", + "9.5|s|04/05:03->10/04:02": "4/adelaide,4/broken_hill,4/south,4/yancowinna", + "9.5|s": "4/darwin,4/north", + "8|s": "12/casey,2/makassar,4/perth,2/ujung_pandang,4/west", + "8|n": "2/brunei,2/hong_kong,2/irkutsk,2/kuala_lumpur,2/kuching,2/macau,2/manila,2/shanghai,2/singapore,2/taipei,2/ulaanbaatar,2/chongqing,2/chungking,2/harbin,2/macao,2/ulan_bator,2/choibalsan,hongkong,prc,roc,singapore", + "8.75|s": "4/eucla", + "7|s": "12/davis,2/jakarta,2/pontianak,9/christmas", + "7|n": "2/bangkok,2/barnaul,2/hovd,2/krasnoyarsk,2/novokuznetsk,2/novosibirsk,2/phnom_penh,2/ho_chi_minh,2/tomsk,2/vientiane,2/saigon", + "6|s": "9/chagos", + "6|n": "2/bishkek,2/dhaka,2/omsk,2/thimphu,2/urumqi,2/dacca,2/kashgar,2/thimbu", + "6.5|s": "9/cocos", + "6.5|n": "2/yangon,2/rangoon", + "5|s": "12/mawson,12/vostok,9/kerguelen", + "5|n": "2/almaty,2/aqtau,2/aqtobe,2/ashgabat,2/atyrau,2/dushanbe,2/karachi,2/oral,2/qyzylorda,2/qostanay,2/samarkand,2/tashkent,2/yekaterinburg,9/maldives,2/ashkhabad", + "5.75|n": "2/kathmandu,2/katmandu", + "5.5|n": "2/kolkata,2/colombo,2/calcutta", + "4|s": "9/mahe,9/mauritius,9/reunion", + "4|n": "2/baku,2/dubai,2/muscat,2/tbilisi,2/yerevan,8/astrakhan,8/samara,8/saratov,8/ulyanovsk", + "4.5|n": "2/kabul", + "3|s": "0/dar_es_salaam,0/nairobi,12/syowa,9/antananarivo,9/comoro,9/mayotte", + "3|n|04/24:00->10/29:24": "0/cairo,egypt", + "3|n|03/29:03->10/25:04": "2/famagusta,2/nicosia,8/athens,8/bucharest,8/chisinau,8/helsinki,8/kyiv,8/mariehamn,8/riga,8/sofia,8/tallinn,8/uzhgorod,8/vilnius,8/zaporozhye,8/nicosia,8/tiraspol,8/kiev,eet", + "3|n|03/29:00->10/24:24": "2/beirut", + "3|n|03/28:02->10/24:02": "2/gaza,2/hebron", + "3|n|03/27:02->10/25:02": "2/jerusalem,2/tel_aviv,israel", + "3|n": "0/addis_ababa,0/asmara,0/asmera,0/djibouti,0/kampala,0/mogadishu,2/aden,2/amman,2/baghdad,2/bahrain,2/damascus,2/kuwait,2/qatar,2/riyadh,8/istanbul,8/kirov,8/minsk,8/moscow,8/simferopol,8/volgograd,2/volgograd,2/istanbul,turkey,w-su", + "3.5|n": "2/tehran,iran", + "2|s": "0/blantyre,0/bujumbura,0/gaborone,0/harare,0/johannesburg,0/kigali,0/lubumbashi,0/lusaka,0/maputo,0/maseru,0/mbabane,0/windhoek", + "2|n|03/29:02->10/25:03": "0/ceuta,arctic/longyearbyen,8/amsterdam,8/andorra,8/belgrade,8/berlin,8/bratislava,8/brussels,8/budapest,8/busingen,8/copenhagen,8/gibraltar,8/ljubljana,8/luxembourg,8/madrid,8/malta,8/monaco,8/oslo,8/paris,8/podgorica,8/prague,8/rome,8/san_marino,8/sarajevo,8/skopje,8/stockholm,8/tirane,8/vaduz,8/vatican,8/vienna,8/warsaw,8/zagreb,8/zurich,3/jan_mayen,poland,cet,met", + "2|n|03/29:01->10/25:03": "12/troll", + "2|n": "0/juba,0/khartoum,0/tripoli,8/kaliningrad,libya", + "1|s": "0/brazzaville,0/kinshasa,0/luanda", + "1|n|03/29:01->10/25:02": "3/canary,3/faroe,3/madeira,8/dublin,8/guernsey,8/isle_of_man,8/jersey,8/lisbon,8/london,3/faeroe,eire,8/belfast,gb-eire,gb,portugal,wet", + "1|n": "0/algiers,0/bangui,0/douala,0/lagos,0/libreville,0/malabo,0/ndjamena,0/niamey,0/porto-novo,0/tunis", + "14|n": "11/kiritimati", + "13|s": "11/apia,11/enderbury,11/kanton,11/fakaofo,11/tongatapu", + "12|s|04/05:03->09/27:02": "12/mcmurdo,11/auckland,12/south_pole,nz", + "12|s": "11/fiji,11/funafuti,11/nauru,11/wallis", + "12|n": "2/anadyr,2/kamchatka,11/kwajalein,11/majuro,11/tarawa,11/wake,kwajalein", + "12.75|s|04/05:03:45->09/27:02:45": "11/chatham,nz-chat", + "11|s|04/05:03->10/04:02": "11/norfolk", + "11|s": "11/bougainville,11/efate,11/guadalcanal,11/noumea", + "11|n": "2/magadan,2/sakhalin,2/srednekolymsk,11/kosrae,11/pohnpei,11/ponape", + "10|s|04/05:03->10/04:02": "12/macquarie,4/currie,4/hobart,4/melbourne,4/sydney,4/act,4/canberra,4/nsw,4/tasmania,4/victoria", + "10|s": "12/dumontdurville,4/brisbane,4/lindeman,11/port_moresby,4/queensland", + "10|n": "2/ust-nera,2/vladivostok,11/guam,11/saipan,11/chuuk,11/truk,11/yap", + "10.5|s|04/05:02->10/04:02": "4/lord_howe,4/lhi", + "0|s|02/15:03->09/20:02": "0/casablanca", + "0|s|02/15:03->03/22:02": "0/el_aaiun", + "0|s": "3/st_helena", + "0|n|03/29:00->10/25:01": "3/azores", + "0|n": "0/abidjan,0/accra,0/bamako,0/banjul,0/bissau,0/conakry,0/dakar,0/freetown,0/lome,0/monrovia,0/nouakchott,0/ouagadougou,0/sao_tome,1/danmarkshavn,3/reykjavik,13/gmt,13/utc,0/timbuktu,13/greenwich,13/uct,13/universal,13/zulu,gmt-0,gmt+0,gmt0,greenwich,iceland,uct,universal,utc,zulu,13/unknown,factory", + "-9|s": "11/gambier", + "-9|n|03/08:02->11/01:02": "1/adak,1/atka,us/aleutian", + "-9.5|s": "11/marquesas", + "-8|s": "11/pitcairn", + "-8|n|03/08:02->11/01:02": "1/anchorage,1/juneau,1/metlakatla,1/nome,1/sitka,1/yakutat,us/alaska", + "-7|n|03/08:02->12/31:23": "1/vancouver,6/pacific", + "-7|n|03/08:02->11/01:02": "1/los_angeles,1/santa_isabel,1/tijuana,1/ensenada,10/bajanorte,us/pacific-new,us/pacific,pst8pdt", + "-7|n": "1/creston,1/dawson,1/dawson_creek,1/fort_nelson,1/hermosillo,1/mazatlan,1/phoenix,1/whitehorse,6/yukon,10/bajasur,us/arizona,mst", + "-6|s|04/04:22->09/05:22": "11/easter,7/easterisland", + "-6|s": "11/galapagos", + "-6|n|03/08:02->12/31:23": "1/edmonton,1/yellowknife,6/mountain", + "-6|n|03/08:02->11/01:02": "1/boise,1/cambridge_bay,1/denver,1/inuvik,1/ciudad_juarez,1/shiprock,navajo,us/mountain,mst7mdt", + "-6|n": "1/bahia_banderas,1/belize,1/chihuahua,1/costa_rica,1/el_salvador,1/guatemala,1/managua,1/merida,1/mexico_city,1/monterrey,1/regina,1/swift_current,1/tegucigalpa,6/east-saskatchewan,6/saskatchewan,10/general", + "-5|s": "1/eirunepe,1/guayaquil,1/lima,1/rio_branco,1/porto_acre,5/acre", + "-5|n|03/08:02->11/01:02": "1/chicago,1/matamoros,1/menominee,1/north_dakota,1/ojinaga,1/rainy_river,1/rankin_inlet,1/resolute,1/winnipeg,1/indiana/knox,1/indiana/tell_city,1/north_dakota/beulah,1/north_dakota/center,1/north_dakota/new_salem,1/knox_in,6/central,us/central,us/indiana-starke,cst6cdt", + "-5|n": "1/bogota,1/cancun,1/cayman,1/coral_harbour,1/jamaica,1/panama,1/atikokan,jamaica,est", + "-4|s|04/04:24->09/06:00": "1/santiago,7/continental", + "-4|s": "1/campo_grande,1/cuiaba,1/la_paz,1/manaus,1/porto_velho,5/west", + "-4|n|03/08:02->11/01:02": "1/detroit,1/grand_turk,1/indiana,1/indianapolis,1/iqaluit,1/kentucky,1/louisville,1/montreal,1/nassau,1/new_york,1/nipigon,1/pangnirtung,1/port-au-prince,1/thunder_bay,1/toronto,1/indiana/marengo,1/indiana/petersburg,1/indiana/vevay,1/indiana/vincennes,1/indiana/winamac,1/kentucky/monticello,1/fort_wayne,1/indiana/indianapolis,1/kentucky/louisville,6/eastern,us/east-indiana,us/eastern,us/michigan,est5edt", + "-4|n|03/08:00->11/01:01": "1/havana,cuba", + "-4|n": "1/anguilla,1/antigua,1/aruba,1/barbados,1/blanc-sablon,1/boa_vista,1/caracas,1/curacao,1/dominica,1/grenada,1/guadeloupe,1/guyana,1/kralendijk,1/lower_princes,1/marigot,1/martinique,1/montserrat,1/port_of_spain,1/puerto_rico,1/santo_domingo,1/st_barthelemy,1/st_kitts,1/st_lucia,1/st_thomas,1/st_vincent,1/tortola,1/virgin", + "-3|s": "1/araguaina,1/argentina,1/asuncion,1/bahia,1/belem,1/buenos_aires,1/catamarca,1/cordoba,1/coyhaique,1/fortaleza,1/jujuy,1/maceio,1/mendoza,1/montevideo,1/punta_arenas,1/recife,1/santarem,1/sao_paulo,12/palmer,12/rothera,3/stanley,1/argentina/la_rioja,1/argentina/rio_gallegos,1/argentina/salta,1/argentina/san_juan,1/argentina/san_luis,1/argentina/tucuman,1/argentina/ushuaia,1/argentina/comodrivadavia,1/argentina/buenos_aires,1/argentina/catamarca,1/argentina/cordoba,1/argentina/jujuy,1/argentina/mendoza,1/argentina/rosario,1/rosario,5/east", + "-3|n|03/08:02->11/01:02": "1/glace_bay,1/goose_bay,1/halifax,1/moncton,1/thule,3/bermuda,6/atlantic", + "-3|n": "1/cayenne,1/paramaribo", + "-2|s": "1/noronha,3/south_georgia,5/denoronha", + "-2|n|03/08:02->11/01:02": "1/miquelon", + "-2.5|n|03/08:02->11/01:02": "1/st_johns,6/newfoundland", + "-1|n|03/28:23->10/24:24": "1/nuuk,1/scoresbysund,1/godthab", + "-1|n": "3/cape_verde", + "-11|s": "11/niue,11/pago_pago,11/samoa,us/samoa", + "-11|n": "11/midway", + "-10|s": "11/rarotonga,11/tahiti", + "-10|n": "11/honolulu,11/johnston,us/hawaii,hst" +} \ No newline at end of file diff --git a/zonefile/iana.js b/zonefile/iana.js new file mode 100644 index 0000000..5b186c8 --- /dev/null +++ b/zonefile/iana.js @@ -0,0 +1,1897 @@ +export default { + 'africa/abidjan': { + offset: 0, + hem: 'n' + }, + 'africa/accra': { + offset: 0, + hem: 'n' + }, + 'africa/addis_ababa': { + offset: 3, + hem: 'n' + }, + 'africa/algiers': { + offset: 1, + hem: 'n' + }, + 'africa/asmara': { + offset: 3, + hem: 'n' + }, + 'africa/asmera': { + offset: 3, + hem: 'n' + }, + 'africa/bamako': { + offset: 0, + hem: 'n' + }, + 'africa/bangui': { + offset: 1, + hem: 'n' + }, + 'africa/banjul': { + offset: 0, + hem: 'n' + }, + 'africa/bissau': { + offset: 0, + hem: 'n' + }, + 'africa/blantyre': { + offset: 2, + hem: 's' + }, + 'africa/brazzaville': { + offset: 1, + hem: 's' + }, + 'africa/bujumbura': { + offset: 2, + hem: 's' + }, + 'africa/cairo': { + offset: 3, + hem: 'n', + dst: '04/24:00->10/29:24' + }, + 'africa/casablanca': { + offset: 0, + hem: 's', + dst: '02/15:03->09/20:02' + }, + 'africa/ceuta': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'africa/conakry': { + offset: 0, + hem: 'n' + }, + 'africa/dakar': { + offset: 0, + hem: 'n' + }, + 'africa/dar_es_salaam': { + offset: 3, + hem: 's' + }, + 'africa/djibouti': { + offset: 3, + hem: 'n' + }, + 'africa/douala': { + offset: 1, + hem: 'n' + }, + 'africa/el_aaiun': { + offset: 0, + hem: 's', + dst: '02/15:03->03/22:02' + }, + 'africa/freetown': { + offset: 0, + hem: 'n' + }, + 'africa/gaborone': { + offset: 2, + hem: 's' + }, + 'africa/harare': { + offset: 2, + hem: 's' + }, + 'africa/johannesburg': { + offset: 2, + hem: 's' + }, + 'africa/juba': { + offset: 2, + hem: 'n' + }, + 'africa/kampala': { + offset: 3, + hem: 'n' + }, + 'africa/khartoum': { + offset: 2, + hem: 'n' + }, + 'africa/kigali': { + offset: 2, + hem: 's' + }, + 'africa/kinshasa': { + offset: 1, + hem: 's' + }, + 'africa/lagos': { + offset: 1, + hem: 'n' + }, + 'africa/libreville': { + offset: 1, + hem: 'n' + }, + 'africa/lome': { + offset: 0, + hem: 'n' + }, + 'africa/luanda': { + offset: 1, + hem: 's' + }, + 'africa/lubumbashi': { + offset: 2, + hem: 's' + }, + 'africa/lusaka': { + offset: 2, + hem: 's' + }, + 'africa/malabo': { + offset: 1, + hem: 'n' + }, + 'africa/maputo': { + offset: 2, + hem: 's' + }, + 'africa/maseru': { + offset: 2, + hem: 's' + }, + 'africa/mbabane': { + offset: 2, + hem: 's' + }, + 'africa/mogadishu': { + offset: 3, + hem: 'n' + }, + 'africa/monrovia': { + offset: 0, + hem: 'n' + }, + 'africa/nairobi': { + offset: 3, + hem: 's' + }, + 'africa/ndjamena': { + offset: 1, + hem: 'n' + }, + 'africa/niamey': { + offset: 1, + hem: 'n' + }, + 'africa/nouakchott': { + offset: 0, + hem: 'n' + }, + 'africa/ouagadougou': { + offset: 0, + hem: 'n' + }, + 'africa/porto-novo': { + offset: 1, + hem: 'n' + }, + 'africa/sao_tome': { + offset: 0, + hem: 'n' + }, + 'africa/tripoli': { + offset: 2, + hem: 'n' + }, + 'africa/tunis': { + offset: 1, + hem: 'n' + }, + 'africa/windhoek': { + offset: 2, + hem: 's' + }, + 'america/adak': { + offset: -9, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/anchorage': { + offset: -8, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/anguilla': { + offset: -4, + hem: 'n' + }, + 'america/antigua': { + offset: -4, + hem: 'n' + }, + 'america/araguaina': { + offset: -3, + hem: 's' + }, + 'america/argentina': { + offset: -3, + hem: 's' + }, + 'america/aruba': { + offset: -4, + hem: 'n' + }, + 'america/asuncion': { + offset: -3, + hem: 's' + }, + 'america/bahia': { + offset: -3, + hem: 's' + }, + 'america/bahia_banderas': { + offset: -6, + hem: 'n' + }, + 'america/barbados': { + offset: -4, + hem: 'n' + }, + 'america/belem': { + offset: -3, + hem: 's' + }, + 'america/belize': { + offset: -6, + hem: 'n' + }, + 'america/blanc-sablon': { + offset: -4, + hem: 'n' + }, + 'america/boa_vista': { + offset: -4, + hem: 'n' + }, + 'america/bogota': { + offset: -5, + hem: 'n' + }, + 'america/boise': { + offset: -6, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/buenos_aires': { + offset: -3, + hem: 's' + }, + 'america/cambridge_bay': { + offset: -6, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/campo_grande': { + offset: -4, + hem: 's' + }, + 'america/cancun': { + offset: -5, + hem: 'n' + }, + 'america/caracas': { + offset: -4, + hem: 'n' + }, + 'america/catamarca': { + offset: -3, + hem: 's' + }, + 'america/cayenne': { + offset: -3, + hem: 'n' + }, + 'america/cayman': { + offset: -5, + hem: 'n' + }, + 'america/chicago': { + offset: -5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/chihuahua': { + offset: -6, + hem: 'n' + }, + 'america/coral_harbour': { + offset: -5, + hem: 'n' + }, + 'america/cordoba': { + offset: -3, + hem: 's' + }, + 'america/costa_rica': { + offset: -6, + hem: 'n' + }, + 'america/coyhaique': { + offset: -3, + hem: 's' + }, + 'america/creston': { + offset: -7, + hem: 'n' + }, + 'america/cuiaba': { + offset: -4, + hem: 's' + }, + 'america/curacao': { + offset: -4, + hem: 'n' + }, + 'america/danmarkshavn': { + offset: 0, + hem: 'n' + }, + 'america/dawson': { + offset: -7, + hem: 'n' + }, + 'america/dawson_creek': { + offset: -7, + hem: 'n' + }, + 'america/denver': { + offset: -6, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/detroit': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/dominica': { + offset: -4, + hem: 'n' + }, + 'america/edmonton': { + offset: -6, + hem: 'n', + dst: '03/08:02->12/31:23' //dst is permanent now + }, + 'america/eirunepe': { + offset: -5, + hem: 's' + }, + 'america/el_salvador': { + offset: -6, + hem: 'n' + }, + 'america/fort_nelson': { + offset: -7, + hem: 'n' + }, + 'america/fortaleza': { + offset: -3, + hem: 's' + }, + 'america/glace_bay': { + offset: -3, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/nuuk': { + offset: -1, + hem: 'n', + dst: '03/28:23->10/24:24' + }, + 'america/goose_bay': { + offset: -3, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/grand_turk': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/grenada': { + offset: -4, + hem: 'n' + }, + 'america/guadeloupe': { + offset: -4, + hem: 'n' + }, + 'america/guatemala': { + offset: -6, + hem: 'n' + }, + 'america/guayaquil': { + offset: -5, + hem: 's' + }, + 'america/guyana': { + offset: -4, + hem: 'n' + }, + 'america/halifax': { + offset: -3, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/havana': { + offset: -4, + hem: 'n', + dst: '03/08:00->11/01:01' + }, + 'america/hermosillo': { + offset: -7, + hem: 'n' + }, + 'america/indiana': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/indianapolis': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/inuvik': { + offset: -6, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/iqaluit': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/jamaica': { + offset: -5, + hem: 'n' + }, + 'america/jujuy': { + offset: -3, + hem: 's' + }, + 'america/juneau': { + offset: -8, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/kentucky': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/kralendijk': { + offset: -4, + hem: 'n' + }, + 'america/la_paz': { + offset: -4, + hem: 's' + }, + 'america/lima': { + offset: -5, + hem: 's' + }, + 'america/los_angeles': { + offset: -7, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/louisville': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/lower_princes': { + offset: -4, + hem: 'n' + }, + 'america/maceio': { + offset: -3, + hem: 's' + }, + 'america/managua': { + offset: -6, + hem: 'n' + }, + 'america/manaus': { + offset: -4, + hem: 's' + }, + 'america/marigot': { + offset: -4, + hem: 'n' + }, + 'america/martinique': { + offset: -4, + hem: 'n' + }, + 'america/matamoros': { + offset: -5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/mazatlan': { + offset: -7, + hem: 'n' + }, + 'america/mendoza': { + offset: -3, + hem: 's' + }, + 'america/menominee': { + offset: -5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/merida': { + offset: -6, + hem: 'n' + }, + 'america/metlakatla': { + offset: -8, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/mexico_city': { + offset: -6, + hem: 'n' + }, + 'america/miquelon': { + offset: -2, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/moncton': { + offset: -3, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/monterrey': { + offset: -6, + hem: 'n' + }, + 'america/montevideo': { + offset: -3, + hem: 's' + }, + 'america/montreal': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/montserrat': { + offset: -4, + hem: 'n' + }, + 'america/nassau': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/new_york': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/nipigon': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/nome': { + offset: -8, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/noronha': { + offset: -2, + hem: 's' + }, + 'america/north_dakota': { + offset: -5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/ojinaga': { + offset: -5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/ciudad_juarez': { + offset: -6, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/panama': { + offset: -5, + hem: 'n' + }, + 'america/pangnirtung': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/paramaribo': { + offset: -3, + hem: 'n' + }, + 'america/phoenix': { + offset: -7, + hem: 'n' + }, + 'america/port-au-prince': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/port_of_spain': { + offset: -4, + hem: 'n' + }, + 'america/porto_velho': { + offset: -4, + hem: 's' + }, + 'america/puerto_rico': { + offset: -4, + hem: 'n' + }, + 'america/punta_arenas': { + offset: -3, + hem: 's' + }, + 'america/rainy_river': { + offset: -5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/rankin_inlet': { + offset: -5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/recife': { + offset: -3, + hem: 's' + }, + 'america/regina': { + offset: -6, + hem: 'n' + }, + 'america/resolute': { + offset: -5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/rio_branco': { + offset: -5, + hem: 's' + }, + 'america/santa_isabel': { + offset: -7, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/santarem': { + offset: -3, + hem: 's' + }, + 'america/santiago': { + offset: -4, + hem: 's', + dst: '04/04:24->09/06:00' + }, + 'america/santo_domingo': { + offset: -4, + hem: 'n' + }, + 'america/sao_paulo': { + offset: -3, + hem: 's' + }, + 'america/scoresbysund': { + offset: -1, + hem: 'n', + dst: '03/28:23->10/24:24' + }, + 'america/sitka': { + offset: -8, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/st_barthelemy': { + offset: -4, + hem: 'n' + }, + 'america/st_johns': { + offset: -2.5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/st_kitts': { + offset: -4, + hem: 'n' + }, + 'america/st_lucia': { + offset: -4, + hem: 'n' + }, + 'america/st_thomas': { + offset: -4, + hem: 'n' + }, + 'america/st_vincent': { + offset: -4, + hem: 'n' + }, + 'america/swift_current': { + offset: -6, + hem: 'n' + }, + 'america/tegucigalpa': { + offset: -6, + hem: 'n' + }, + 'america/thule': { + offset: -3, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/thunder_bay': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/tijuana': { + offset: -7, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/toronto': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/tortola': { + offset: -4, + hem: 'n' + }, + 'america/vancouver': { + "offset": -7, + "hem": "n", + dst: '03/08:02->12/31:23' //dst is permanent now + }, + 'america/whitehorse': { + offset: -7, + hem: 'n' + }, + 'america/winnipeg': { + offset: -5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/yakutat': { + offset: -8, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/yellowknife': { + offset: -6, + hem: 'n', + dst: '03/08:02->12/31:23' //dst is permanent now + }, + 'antarctica/casey': { + offset: 8, + hem: 's' + }, + 'antarctica/davis': { + offset: 7, + hem: 's' + }, + 'antarctica/dumontdurville': { + offset: 10, + hem: 's' + }, + 'antarctica/macquarie': { + offset: 10, + hem: 's', + dst: '04/05:03->10/04:02' + }, + 'antarctica/mawson': { + offset: 5, + hem: 's' + }, + 'antarctica/mcmurdo': { + offset: 12, + hem: 's', + dst: '04/05:03->09/27:02' + }, + 'antarctica/palmer': { + offset: -3, + hem: 's' + }, + 'antarctica/rothera': { + offset: -3, + hem: 's' + }, + 'antarctica/syowa': { + offset: 3, + hem: 's' + }, + 'antarctica/troll': { + offset: 2, + hem: 'n', + dst: '03/29:01->10/25:03' + }, + 'antarctica/vostok': { + offset: 5, + hem: 's' + }, + 'arctic/longyearbyen': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'asia/aden': { + offset: 3, + hem: 'n' + }, + 'asia/almaty': { + offset: 5, + hem: 'n' + }, + 'asia/amman': { + offset: 3, + hem: 'n' + }, + 'asia/anadyr': { + offset: 12, + hem: 'n' + }, + 'asia/aqtau': { + offset: 5, + hem: 'n' + }, + 'asia/aqtobe': { + offset: 5, + hem: 'n' + }, + 'asia/ashgabat': { + offset: 5, + hem: 'n' + }, + 'asia/atyrau': { + offset: 5, + hem: 'n' + }, + 'asia/baghdad': { + offset: 3, + hem: 'n' + }, + 'asia/bahrain': { + offset: 3, + hem: 'n' + }, + 'asia/baku': { + offset: 4, + hem: 'n' + }, + 'asia/bangkok': { + offset: 7, + hem: 'n' + }, + 'asia/barnaul': { + offset: 7, + hem: 'n' + }, + 'asia/beirut': { + offset: 3, + hem: 'n', + dst: '03/29:00->10/24:24' + }, + 'asia/bishkek': { + offset: 6, + hem: 'n' + }, + 'asia/brunei': { + offset: 8, + hem: 'n' + }, + 'asia/kolkata': { + offset: 5.5, + hem: 'n' + }, + 'asia/chita': { + offset: 9, + hem: 'n' + }, + 'asia/colombo': { + offset: 5.5, + hem: 'n' + }, + 'asia/damascus': { + offset: 3, + hem: 'n' + }, + 'asia/dhaka': { + offset: 6, + hem: 'n' + }, + 'asia/dili': { + offset: 9, + hem: 's' + }, + 'asia/dubai': { + offset: 4, + hem: 'n' + }, + 'asia/dushanbe': { + offset: 5, + hem: 'n' + }, + 'asia/famagusta': { + offset: 3, + hem: 'n', + dst: '03/29:03->10/25:04' + }, + 'asia/gaza': { + offset: 3, + hem: 'n', + dst: '03/28:02->10/24:02' + }, + 'asia/hebron': { + offset: 3, + hem: 'n', + dst: '03/28:02->10/24:02' + }, + 'asia/hong_kong': { + offset: 8, + hem: 'n' + }, + 'asia/hovd': { + offset: 7, + hem: 'n' + }, + 'asia/irkutsk': { + offset: 8, + hem: 'n' + }, + 'asia/jakarta': { + offset: 7, + hem: 's' + }, + 'asia/jayapura': { + offset: 9, + hem: 's' + }, + 'asia/jerusalem': { + offset: 3, + hem: 'n', + dst: '03/27:02->10/25:02' + }, + 'asia/kabul': { + offset: 4.5, + hem: 'n' + }, + 'asia/kamchatka': { + offset: 12, + hem: 'n' + }, + 'asia/karachi': { + offset: 5, + hem: 'n' + }, + 'asia/kathmandu': { + offset: 5.75, + hem: 'n' + }, + 'asia/khandyga': { + offset: 9, + hem: 'n' + }, + 'asia/krasnoyarsk': { + offset: 7, + hem: 'n' + }, + 'asia/kuala_lumpur': { + offset: 8, + hem: 'n' + }, + 'asia/kuching': { + offset: 8, + hem: 'n' + }, + 'asia/kuwait': { + offset: 3, + hem: 'n' + }, + 'asia/macau': { + offset: 8, + hem: 'n' + }, + 'asia/magadan': { + offset: 11, + hem: 'n' + }, + 'asia/makassar': { + offset: 8, + hem: 's' + }, + 'asia/manila': { + offset: 8, + hem: 'n' + }, + 'asia/muscat': { + offset: 4, + hem: 'n' + }, + 'asia/nicosia': { + offset: 3, + hem: 'n', + dst: '03/29:03->10/25:04' + }, + 'asia/novokuznetsk': { + offset: 7, + hem: 'n' + }, + 'asia/novosibirsk': { + offset: 7, + hem: 'n' + }, + 'asia/omsk': { + offset: 6, + hem: 'n' + }, + 'asia/oral': { + offset: 5, + hem: 'n' + }, + 'asia/phnom_penh': { + offset: 7, + hem: 'n' + }, + 'asia/pontianak': { + offset: 7, + hem: 's' + }, + 'asia/pyongyang': { + offset: 9, + hem: 'n' + }, + 'asia/qatar': { + offset: 3, + hem: 'n' + }, + 'asia/qyzylorda': { + offset: 5, + hem: 'n' + }, + 'asia/qostanay': { + offset: 5, + hem: 'n' + }, + 'asia/yangon': { + offset: 6.5, + hem: 'n' + }, + 'asia/riyadh': { + offset: 3, + hem: 'n' + }, + 'asia/ho_chi_minh': { + offset: 7, + hem: 'n' + }, + 'asia/sakhalin': { + offset: 11, + hem: 'n' + }, + 'asia/samarkand': { + offset: 5, + hem: 'n' + }, + 'asia/seoul': { + offset: 9, + hem: 'n' + }, + 'asia/shanghai': { + offset: 8, + hem: 'n' + }, + 'asia/singapore': { + offset: 8, + hem: 'n' + }, + 'asia/srednekolymsk': { + offset: 11, + hem: 'n' + }, + 'asia/taipei': { + offset: 8, + hem: 'n' + }, + 'asia/tashkent': { + offset: 5, + hem: 'n' + }, + 'asia/tbilisi': { + offset: 4, + hem: 'n' + }, + 'asia/tehran': { + offset: 3.5, + hem: 'n' + }, + 'asia/thimphu': { + offset: 6, + hem: 'n' + }, + 'asia/tokyo': { + offset: 9, + hem: 'n' + }, + 'asia/tomsk': { + offset: 7, + hem: 'n' + }, + 'asia/ulaanbaatar': { + offset: 8, + hem: 'n' + }, + 'asia/urumqi': { + offset: 6, + hem: 'n' + }, + 'asia/ust-nera': { + offset: 10, + hem: 'n' + }, + 'asia/vientiane': { + offset: 7, + hem: 'n' + }, + 'asia/vladivostok': { + offset: 10, + hem: 'n' + }, + 'asia/yakutsk': { + offset: 9, + hem: 'n' + }, + 'asia/yekaterinburg': { + offset: 5, + hem: 'n' + }, + 'asia/yerevan': { + offset: 4, + hem: 'n' + }, + 'atlantic/azores': { + offset: 0, + hem: 'n', + dst: '03/29:00->10/25:01' + }, + 'atlantic/bermuda': { + offset: -3, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'atlantic/canary': { + offset: 1, + hem: 'n', + dst: '03/29:01->10/25:02' + }, + 'atlantic/cape_verde': { + offset: -1, + hem: 'n' + }, + 'atlantic/faroe': { + offset: 1, + hem: 'n', + dst: '03/29:01->10/25:02' + }, + 'atlantic/madeira': { + offset: 1, + hem: 'n', + dst: '03/29:01->10/25:02' + }, + 'atlantic/reykjavik': { + offset: 0, + hem: 'n' + }, + 'atlantic/south_georgia': { + offset: -2, + hem: 's' + }, + 'atlantic/st_helena': { + offset: 0, + hem: 's' + }, + 'atlantic/stanley': { + offset: -3, + hem: 's' + }, + 'australia/adelaide': { + offset: 9.5, + hem: 's', + dst: '04/05:03->10/04:02' + }, + 'australia/brisbane': { + offset: 10, + hem: 's' + }, + 'australia/broken_hill': { + offset: 9.5, + hem: 's', + dst: '04/05:03->10/04:02' + }, + 'australia/currie': { + offset: 10, + hem: 's', + dst: '04/05:03->10/04:02' + }, + 'australia/darwin': { + offset: 9.5, + hem: 's' + }, + 'australia/eucla': { + offset: 8.75, + hem: 's' + }, + 'australia/hobart': { + offset: 10, + hem: 's', + dst: '04/05:03->10/04:02' + }, + 'australia/lindeman': { + offset: 10, + hem: 's' + }, + 'australia/lord_howe': { + offset: 10.5, + hem: 's', + dst: '04/05:02->10/04:02' + }, + 'australia/melbourne': { + offset: 10, + hem: 's', + dst: '04/05:03->10/04:02' + }, + 'australia/perth': { + offset: 8, + hem: 's' + }, + 'australia/sydney': { + offset: 10, + hem: 's', + dst: '04/05:03->10/04:02' + }, + 'europe/amsterdam': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/andorra': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/astrakhan': { + offset: 4, + hem: 'n' + }, + 'europe/athens': { + offset: 3, + hem: 'n', + dst: '03/29:03->10/25:04' + }, + 'europe/belgrade': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/berlin': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/bratislava': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/brussels': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/bucharest': { + offset: 3, + hem: 'n', + dst: '03/29:03->10/25:04' + }, + 'europe/budapest': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/busingen': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/chisinau': { + "offset": 3, + "hem": "n", + "dst": "03/29:03->10/25:04" + }, + 'europe/copenhagen': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/dublin': { + offset: 1, + hem: 'n', + dst: '03/29:01->10/25:02' + }, + 'europe/gibraltar': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/guernsey': { + offset: 1, + hem: 'n', + dst: '03/29:01->10/25:02' + }, + 'europe/helsinki': { + offset: 3, + hem: 'n', + dst: '03/29:03->10/25:04' + }, + 'europe/isle_of_man': { + offset: 1, + hem: 'n', + dst: '03/29:01->10/25:02' + }, + 'europe/istanbul': { + offset: 3, + hem: 'n' + }, + 'europe/jersey': { + offset: 1, + hem: 'n', + dst: '03/29:01->10/25:02' + }, + 'europe/kaliningrad': { + offset: 2, + hem: 'n' + }, + 'europe/kirov': { + offset: 3, + hem: 'n' + }, + 'europe/kyiv': { + offset: 3, + hem: 'n', + dst: '03/29:03->10/25:04' + }, + 'europe/lisbon': { + offset: 1, + hem: 'n', + dst: '03/29:01->10/25:02' + }, + 'europe/ljubljana': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/london': { + offset: 1, + hem: 'n', + dst: '03/29:01->10/25:02' + }, + 'europe/luxembourg': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/madrid': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/malta': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/mariehamn': { + offset: 3, + hem: 'n', + dst: '03/29:03->10/25:04' + }, + 'europe/minsk': { + offset: 3, + hem: 'n' + }, + 'europe/monaco': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/moscow': { + offset: 3, + hem: 'n' + }, + 'europe/oslo': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/paris': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/podgorica': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/prague': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/riga': { + offset: 3, + hem: 'n', + dst: '03/29:03->10/25:04' + }, + 'europe/rome': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/samara': { + offset: 4, + hem: 'n' + }, + 'europe/saratov': { + offset: 4, + hem: 'n' + }, + 'europe/san_marino': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/sarajevo': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/simferopol': { + offset: 3, + hem: 'n' + }, + 'europe/skopje': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/sofia': { + offset: 3, + hem: 'n', + dst: '03/29:03->10/25:04' + }, + 'europe/stockholm': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/tallinn': { + offset: 3, + hem: 'n', + dst: '03/29:03->10/25:04' + }, + 'europe/tirane': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/ulyanovsk': { + offset: 4, + hem: 'n' + }, + 'europe/uzhgorod': { + offset: 3, + hem: 'n', + dst: '03/29:03->10/25:04' + }, + 'europe/vaduz': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/vatican': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/vienna': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/vilnius': { + offset: 3, + hem: 'n', + dst: '03/29:03->10/25:04' + }, + 'europe/volgograd': { + offset: 3, + hem: 'n' + }, + 'europe/warsaw': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/zagreb': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'europe/zaporozhye': { + offset: 3, + hem: 'n', + dst: '03/29:03->10/25:04' + }, + 'europe/zurich': { + offset: 2, + hem: 'n', + dst: '03/29:02->10/25:03' + }, + 'indian/antananarivo': { + offset: 3, + hem: 's' + }, + 'indian/chagos': { + offset: 6, + hem: 's' + }, + 'indian/christmas': { + offset: 7, + hem: 's' + }, + 'indian/cocos': { + offset: 6.5, + hem: 's' + }, + 'indian/comoro': { + offset: 3, + hem: 's' + }, + 'indian/kerguelen': { + offset: 5, + hem: 's' + }, + 'indian/mahe': { + offset: 4, + hem: 's' + }, + 'indian/maldives': { + offset: 5, + hem: 'n' + }, + 'indian/mauritius': { + offset: 4, + hem: 's' + }, + 'indian/mayotte': { + offset: 3, + hem: 's' + }, + 'indian/reunion': { + offset: 4, + hem: 's' + }, + 'pacific/apia': { + offset: 13, + hem: 's' + }, + 'pacific/auckland': { + offset: 12, + hem: 's', + dst: '04/05:03->09/27:02' + }, + 'pacific/bougainville': { + offset: 11, + hem: 's' + }, + 'pacific/chatham': { + offset: 12.75, + hem: 's', + dst: '04/05:03:45->09/27:02:45' + }, + 'pacific/easter': { + offset: -6, + hem: 's', + dst: '04/04:22->09/05:22' + }, + 'pacific/efate': { + offset: 11, + hem: 's' + }, + 'pacific/enderbury': { + offset: 13, + hem: 'n' + }, + 'pacific/kanton': { + offset: 13, + hem: 's' + }, + 'america/atikokan': { + offset: -5, + hem: 'n' + }, + 'pacific/fakaofo': { + offset: 13, + hem: 's' + }, + 'pacific/fiji': { + offset: 12, + hem: 's' + }, + 'pacific/funafuti': { + offset: 12, + hem: 's' + }, + 'pacific/galapagos': { + offset: -6, + hem: 's' + }, + 'pacific/gambier': { + offset: -9, + hem: 's' + }, + 'pacific/guadalcanal': { + offset: 11, + hem: 's' + }, + 'pacific/guam': { + offset: 10, + hem: 'n' + }, + 'pacific/honolulu': { + offset: -10, + hem: 'n' + }, + 'pacific/johnston': { + offset: -10, + hem: 'n' + }, + 'pacific/kiritimati': { + offset: 14, + hem: 'n' + }, + 'pacific/kosrae': { + offset: 11, + hem: 'n' + }, + 'pacific/kwajalein': { + offset: 12, + hem: 'n' + }, + 'pacific/majuro': { + offset: 12, + hem: 'n' + }, + 'pacific/marquesas': { + offset: -9.5, + hem: 's' + }, + 'pacific/midway': { + offset: -11, + hem: 'n' + }, + 'pacific/nauru': { + offset: 12, + hem: 's' + }, + 'pacific/niue': { + offset: -11, + hem: 's' + }, + 'pacific/norfolk': { + offset: 11, + hem: 's', + dst: '04/05:03->10/04:02' + }, + 'pacific/noumea': { + offset: 11, + hem: 's' + }, + 'pacific/pago_pago': { + offset: -11, + hem: 's' + }, + 'pacific/palau': { + offset: 9, + hem: 'n' + }, + 'pacific/pitcairn': { + offset: -8, + hem: 's' + }, + 'pacific/pohnpei': { + offset: 11, + hem: 'n' + }, + 'pacific/port_moresby': { + offset: 10, + hem: 's' + }, + 'pacific/rarotonga': { + offset: -10, + hem: 's' + }, + 'pacific/saipan': { + offset: 10, + hem: 'n' + }, + 'pacific/tahiti': { + offset: -10, + hem: 's' + }, + 'pacific/tarawa': { + offset: 12, + hem: 'n' + }, + 'pacific/tongatapu': { + offset: 13, + hem: 's' + }, + 'pacific/chuuk': { + offset: 10, + hem: 'n' + }, + 'pacific/wake': { + offset: 12, + hem: 'n' + }, + 'pacific/wallis': { + offset: 12, + hem: 's' + }, + 'etc/gmt': { + offset: 0, + hem: 'n' + }, + 'etc/utc': { + offset: 0, + hem: 'n' + }, + 'america/argentina/la_rioja': { + offset: -3, + hem: 's' + }, + 'america/argentina/rio_gallegos': { + offset: -3, + hem: 's' + }, + 'america/argentina/salta': { + offset: -3, + hem: 's' + }, + 'america/argentina/san_juan': { + offset: -3, + hem: 's' + }, + 'america/argentina/san_luis': { + offset: -3, + hem: 's' + }, + 'america/argentina/tucuman': { + offset: -3, + hem: 's' + }, + 'america/argentina/ushuaia': { + offset: -3, + hem: 's' + }, + 'america/indiana/knox': { + offset: -5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/indiana/tell_city': { + offset: -5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/north_dakota/beulah': { + offset: -5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/north_dakota/center': { + offset: -5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/north_dakota/new_salem': { + offset: -5, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/indiana/marengo': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/indiana/petersburg': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/indiana/vevay': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/indiana/vincennes': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/indiana/winamac': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + }, + 'america/kentucky/monticello': { + offset: -4, + hem: 'n', + dst: '03/08:02->11/01:02' + } +} diff --git a/zonefile/pack.js b/zonefile/pack.js new file mode 100644 index 0000000..61f8f72 --- /dev/null +++ b/zonefile/pack.js @@ -0,0 +1,47 @@ +//turn our timezone data into a small-as-possible string +import { writeFileSync } from 'node:fs' +import iana from './iana.js' +import aliases from './aliases.js' +import prefixes from './_prefixes.js' +const all = {} + +// add aliases in +Object.keys(aliases).forEach((k) => { + const found = iana[aliases[k]] + if (!found) { + console.log('missing', aliases[k]) //eslint-disable-line + } + iana[k] = Object.assign({}, found) +}) + +//pack iana data into a [o|h] object +Object.keys(iana).forEach((k) => { + const o = iana[k] + let key = o.offset + '|' + o.hem + if (o.dst) { + key += '|' + o.dst + } + all[key] = all[key] || [] + const name = k.replace(/(.*?)\//, (a, prefix) => { + const index = prefixes.indexOf(prefix) + if (index !== -1) { + return index + '/' + } + return a + }) + all[key].push(name) +}) + +//add-in informal abbreviations +// all = addHemisphere(all, informal.south, 's') +// all = addHemisphere(all, informal.north, 'n') + +let keys = Object.keys(all) +keys = keys.sort((a, b) => (a < b ? 1 : -1)) +const result = {} +keys.forEach((k) => { + result[k] = all[k].join(',') +}) + +// console.log(result) +writeFileSync('./zonefile/_build.js', 'export default ' + JSON.stringify(result, null, 2))