Upstream spencermountain/spacetime state of the touched files before fe90cae667
This commit is contained in:
1 parent
081c965030
commit
d47824c8f3
6 files changed
+2406
No files matched your search
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
Vendored
+94
@@ -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<number>, 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
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
+1897
File diff suppressed because it is too large.
Load diff
@@ -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))
|
||||
Reference in new issue
Block a user