Giter VIP home page Giter VIP logo

therootcompany / tz.js Goto Github PK

View Code? Open in Web Editor NEW
12.0 2.0 2.0 162 KB

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

Home Page: https://therootcompany.github.io/tz.js/

License: Other

JavaScript 73.27% HTML 26.73%
tz timezone-conversion timezones timezone nodejs node node-js javascript browser webpack

tz.js's Introduction

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+Offset format?

TZ.toLocalISOString(new Date()); // "2021-11-07T03:15:59.000-0500"
TZ.timeZone(); // "America/New_York"
// What will the ISO+Offset datetime string be
// when it's 3:15am in New York?
//
// (Relative New York time to Absolute ISO+Offset Time)

TZ.toOffsetISOString("2021-11-07 03:15:59.000", "America/New_York");
// "2021-11-07T03:15:59.000-0500"
// What time will it be in New York
// when it's 7:15am UTC?
//
// (Absolute UTC Zulu time to Relative New York time)

TZ.toTimeZoneISOString("2021-03-14T07:15:59.000Z", "America/New_York");
// "2021-03-14T03:15:59.000-0400"

Features

  • Translate a UTC Zulu time to a Time Zone
  • Translate a Zoned time to ISO+Offset
  • 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/.

How was this built?

I live-streamed the creation of this entire project.

If you'd like to learn how I did it and what challenges I encountered, you can watch here: https://www.youtube.com/playlist?list=PLxki0D-ilnqa6horOJ2G18WMZlJeQFlAt

(though there have been a few minor updates and bug fixes off-camera)

API

  • toLocalISOString(dateOrNull)
  • toTimeZone(utcDate, timeZone)
  • toTimeZoneISOString(isoString, timeZone)
  • fromTimeZone(dtString, timeZone)
  • toOffsetISOString(dtString, timeZone)

toTimeZone(utcDate, timeZone)

Convert UTC into a Target Time Zone

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

"2021-11-07T08:15:59.000Z"
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")

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 ISO 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"

fromTimeZone(dtString, timeZone)

Convert a Target Time Zone into ISO

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

"2021-11-0 03:15:59.000"
var tzDate = TZ.fromTimeZone("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")

Convert directly to an offset ISO String:

TZ.toOffsetISOString("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.fromTimeZone("2021-11-07 03:15:59.000", "America/New_York");

Use a Date as a source time

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.fromTimeZone(
  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.fromTimeZone("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.fromTimeZone("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)

tz.js's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

tz.js's Issues

demo shows a .timeZone function that doesn't actually exist

> TZ
{
  toOffsetISOString: [Function: toOffsetISOString],
  formatOffset: [Function: formatOffset],
  toLocalISOString: [Function: toLocalISOString],
  toTimeZone: [Function: toTimeZone],
  toTimeZoneISOString: [Function: toTimeZoneISOString],
  toUTC: [Function: fromTimeZone],
  fromTimeZone: [Function: fromTimeZone],
  toUTCISOString: [Function: toOffsetISOString]
}
> TZ.timeZone();
Uncaught TypeError: TZ.timeZone is not a function

Suggestion for date object returned by toUTC

I see that toUTC returns an object. I find this preferable to the way other libraries do it because then I can build out the format I need. However, I don't have all the pieces I really want.

Would it be better for the object to contain all the formats of the various date parts according to the unicode symbols? Intl.DateTimeFormat().resolvedOptions().timeZone;

npm files list

This is packing a few files that npm doesn't need and making it look bigger than it really is.

Use current local timezone when none is specified

datetime-local does not accept a format that the Date object can provide, and does not give a format that the Date object understands...

<input type="datetime-local"></input>

The datetime-local requires the value in the format YYYY-MM-DDThh:mm[:ss[.sss]]. For this use case it would be nice to be able to do XTZ.toUTC(new date()).toISOString() or XTZ.toISOLocaleString(new Date())... or something

function (x, tz = new Intl.DateTimeFormat().resolvedOptions().timeZone) {
  // ...
}

Also, the name toUTC may be misleading... it's more like toUTCOffset or toISOOffset.

Add `xtzDate.toDate()`

Either of these would work:

xtzDate.toDate = function () {
  return new Date(xtzDate.toISOString());
};
xtzDate.toDate = function () {
  return new Date(xtzDate.year, xtzDate.month, xtzDate.date, xtzDate.hour, xtzDate.minute, xtzDate.second, xtzDate.millisecond);
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.