tz.js/README.md

5.6 KiB

xtz.js

A fast, lightweight, zero-dependency library to translate between Time Zones and UTC with native Intl.DateTimeFormat in ~100 LoC. For Node.js & Browsers.

XTZ is a poor man's Temporal polyfill, but just for time zones.
Demo: https://therootcompany.github.io/tz.js/

// What's the current time, in ISO format?

TZ.toLocalISOString(new Date()); // "2021-11-07T03:15:59.000-0500"
TZ.timeZone(); // "America/New_York"

What UTC time will it be when it's 3:15am in New York?

// Relative New York time to Absolute UTC Time
TZ.toUTCISOString("2021-11-07 03:15:59.000", "America/New_York");
// "2021-11-07T03:15:59.000-0500"
var tzDate = TZ.toUTC("2021-11-07 03:15:59.000", "America/New_York");
// {
//   year: 2021, month: 10, day: 7,
//   hour: 3, minute: 15, second: 59, millisecond: 0,
//   offset: -300, timeZoneName: "Eastern Standard Time"
// }

tzDate.toISOString();
// "2021-11-07T03:15:59.000-0500"
// (same as "2021-11-07T08:15:59.000Z")

What time will it be in New York when it's 7:15am UTC?

// Absolute UTC time to Relative New York time
TZ.toTimeZoneISOString("2021-03-14T07:15:59.000Z", "America/New_York");
// "2021-03-14T03:15:59.000-0400"
var utcDate = TZ.toTimeZone("2021-03-14T07:15:59.000Z", "America/New_York");
// {
//   year: 2021, month: 2, day: 14,
//   hour: 3, minute: 15, second: 59, millisecond: 0,
//   offset: -240, timeZoneName: "Eastern Daylight Time"
// }

utcDate.toISOString();
// "2021-03-14T03:15:59.000-0400"
// (same as "2021-11-07T07:15:59.000Z")

Features

  • Translate a UTC time to a Time Zone
  • Translate a Zoned time to UTC
  • Handles Daylight Savings, Weird Time Zones, etc...
    • Well-tested npm run test
  • Lightweight (No deps)
    • 5kb Source + Comments
    • 2.5kb Minified
    • <1kb gzipd

Compatible with Browsers, and Node.js.

Browsers

<script src="https://unpkg.com/xtz@latest/xtz.min.js"></script>
var TZ = window.XTZ;

Node.js & Webpack

npm install --save xtz
var TZ = require("xtz");

Demo

See https://therootcompany.github.io/tz.js/.

API

  • toLocalISOString(dateOrNull)
  • toTimeZone(utcDate, timeZone)
  • toTimeZoneISOString(isoString, timeZone)
  • toUTC(dtString, timeZone)
  • toUTCISOString(dtString, timeZone)

toTimeZone(utcDate, timeZone)

Convert UTC into a Target Time Zone

Use ISO timestamps representing the absolute UTC time (with or without offset):

"2021-11-07T08:15:59.000Z"

Convert directly to an ISO String:

TZ.toTimeZoneISOString("2021-11-07T08:15:59.000Z", "America/New_York");
// "2021-11-07T03:15:59.000-0500"

Or use our bespoke (custom) date object:

var tzDate = TZ.toTimeZone("2021-11-07T08:15:59.000Z", "America/New_York");

You can also use a date object with an absolute UTC time:

var tzDate = TZ.toTimeZone(
  new Date("2021-11-07T08:15:59.000Z"),
  "America/New_York"
);
console.log(tzDate.toISOString());
// "2021-11-07T03:15:59.000-0500"

Our ISO Strings + Offsets work with JavaScript's native Date object!!

new Date("2021-11-07T03:15:59.000-0500").toISOString());
// "2021-11-07T08:15:59.000Z"

toUTC(dtString, timeZone)

Convert a Target Time Zone into UTC

Use ISO-like timestamps representing the local time in the target time zone:

"2021-11-0 03:15:59.000"

Convert directly to an offset ISO String:

TZ.toUTCISOString("2021-11-07 03:15:59.000", "America/New_York");
// "2021-11-07T03:15:59.000-0500"

Or our bespoke date object:

var utcDate = TZ.toUTC("2021-11-07 03:15:59.000", "America/New_York");

You can also use a date object as the source time, but the date's UTC time will be treated as relative to time zone rather than absolute (this is a workaround for JavaScript's lack of bi-directional timezone support).

var utcDate = TZ.toUTC(
  new Date("2021-11-07T03:15:59.000Z"),
  "America/New_York"
);
utcDate.toISOString();
// "2021-11-07T03:15:59.000-0500"

Daylight Savings / Edge Cases

In 2021 Daylight Savings (in the US)

  • begins at 2am on March 14th (skips to 3am)
  • ends at 2am on November 7th (resets to 1am)

See https://www.timeanddate.com/time/change/usa.

Q: What happens in March when 2am is skipped?

  • A: Although 2am is not a valid time, rather than throwing an error this library will resolve to 1am instead, which is an hour early in real ("tick-tock" or "monotonic") time.
    var utcDate = TZ.toUTC("2021-03-14 02:15:59.000", "America/New_York");
    utcDate.toISOString();
    // "2021-03-14T02:15:59.000-0400"
    // (same as "2021-03-14T01:15:59.000-0500")
    

Q: What happens in November when 1am happens twice?

  • A: Although both 1ams are distinguishable with ISO offset times, only the first can be resolved from a local time with this library.
    var utcDate = TZ.toUTC("2021-11-07 01:15:59.000", "America/New_York");
    utcDate.toISOString();
    // "2021-11-07T01:15:59.000-0400", same as "2021-11-07T05:15:59.000Z"
    // (an hour before the 2nd 1am at "2021-11-07T01:15:59.000-0500")
    

List of Time Zones

See the Full List of Time Zones on Wikipedia.

Common Zones for Testing:

America/New_York    -0500
America/Denver      -0700
America/Phoenix     -0700 (No DST)
America/Los_Angeles -0800
UTC                 Z
Australia/Adelaide  +0930 (30-min, has DST)
Asia/Kathmandu      +0545 (No DST, 45-min)
Asia/Kolkata        +0530 (No DST, 30-min)