All Projects → marnusw → Date Fns Tz

marnusw / Date Fns Tz

Licence: mit
Complementary library for date-fns v2 adding IANA time zone support

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Date Fns Tz

Timezone Support
Lightweight time zone support for your applications or other date libraries.
Stars: ✭ 90 (-76.62%)
Mutual labels:  time, date, timezone
Delorean
Delorean: Time Travel Made Easy
Stars: ✭ 1,793 (+365.71%)
Mutual labels:  time, date, timezone
Js Joda
🕑 Immutable date and time library for javascript
Stars: ✭ 1,298 (+237.14%)
Mutual labels:  time, date, timezone
nepali-datetime
Python's core datetime inspired nepali datetime (BS date & NPT) package 🇳🇵
Stars: ✭ 36 (-90.65%)
Mutual labels:  time, date, timezone
temps-lite
A smart, good-looking little app which tries to speak your language the way you are used to.
Stars: ✭ 40 (-89.61%)
Mutual labels:  time, date, timezone
Date Fns
⏳ Modern JavaScript date utility library ⌛️
Stars: ✭ 27,650 (+7081.82%)
Mutual labels:  time, date, utilities
Date Fns Timezone
Parsing and formatting date strings using IANA time zones for date-fns.
Stars: ✭ 118 (-69.35%)
Mutual labels:  time, date, timezone
Luatz
Time, Date and Timezone library for lua
Stars: ✭ 92 (-76.1%)
Mutual labels:  time, date, timezone
timelite
String date and time utilities 🕙
Stars: ✭ 17 (-95.58%)
Mutual labels:  time, utilities, date
Date
A date and time library based on the C++11/14/17 <chrono> header
Stars: ✭ 2,389 (+520.52%)
Mutual labels:  time, date, timezone
Time
Building a better date/time library for Swift
Stars: ✭ 1,983 (+415.06%)
Mutual labels:  time, date, timezone
TimesDates.jl
Nanosecond resolution for Time and Date, TimeZones
Stars: ✭ 28 (-92.73%)
Mutual labels:  time, date, timezone
time machine
A date and time API for Dart
Stars: ✭ 120 (-68.83%)
Mutual labels:  time, date, timezone
hs-hourglass
efficient and simpler time API for haskell
Stars: ✭ 43 (-88.83%)
Mutual labels:  time, date, timezone
moment-cache
⏱ Simple utility to cache moment.js results and speed up moment calls.
Stars: ✭ 29 (-92.47%)
Mutual labels:  time, date
vue-timeselector
🕒 Simply customizable powerful time picker for Vue.js
Stars: ✭ 41 (-89.35%)
Mutual labels:  time, date
date4j
Lightweight alternative to Java's built-in date-time classes. Android-friendly. Compiles under JDK 1.5.
Stars: ✭ 36 (-90.65%)
Mutual labels:  time, date
wareki
Utility function for Japanese calender.
Stars: ✭ 23 (-94.03%)
Mutual labels:  utilities, date
dayjs
Extended fork of Day.js - 2KB immutable date library alternative to Moment.js
Stars: ✭ 36 (-90.65%)
Mutual labels:  time, date
date-php
这是一个Javascript模仿PHP日期时间格式化函数,使用方法和PHP非常类似,有丰富的模板字符,并在原来的基础上增加了一些模板字符。 This is a date function that implement PHP in Javascript. It is very similar to PHP, has rich template characters, and enhances some template characters on the basis of the original.
Stars: ✭ 24 (-93.77%)
Mutual labels:  time, date

date-fns-tz

Time zone support for date-fns v2.0.0 using the Intl API. By using the browser API no time zone data needs to be included in code bundles. Modern browsers all support the necessary features, and for those that don't a polyfill can be used.

If you do not wish to use a polyfill the time zone option can still be used, but only with time zone offsets such as '-0200' or '+04:00' and not IANA time zone names.

Table of Contents

Overview

Working with UTC or ISO date strings is easy, and so is working with JS dates when all times are displayed in a user's local time in the browser. The difficulty comes when working with another time zone's local time, other than the current system's, like on a Node server or when showing the time of an event in a specific time zone, like an event in LA at 8pm PST regardless of where a user resides.

In this case there are two relevant pieces of information:

  • a fixed moment in time in the form of a timestamp, UTC or ISO date string, and
  • the time zone descriptor, usually an offset or IANA time zone name (e.g. America/New_York).

Libraries like Moment and Luxon, which provide their own date time classes, manage these timestamp and time zone values internally. Since date-fns always returns a plain JS Date, which implicitly has the current system's time zone, helper functions are provided for handling common time zone related use cases.

Time Zone Helpers

To discuss the usage of the time zone helpers let's assume we're writing a system where administrators set up events which will start at a specific time in the venue's local time, and this local time should be shown when accessing the site from anywhere in the world.

zonedTimeToUtc

Given a date and any time zone, returns a Date with the equivalent UTC time

zonedTimeToUtc(date: Date|Number|String, timeZone: String): Date

Say a user is asked to input the date/time and time zone of an event. A date/time picker will typically return a Date instance with the chosen date, in the user's local time zone, and a select input might provide the actual IANA time zone name.

In order to work with this info effectively it is necessary to find the equivalent UTC time:

import { zonedTimeToUtc } from 'date-fns-tz'

const date = getDatePickerValue() // e.g. 2014-06-25 10:00:00 (picked in any time zone)
const timeZone = getTimeZoneValue() // e.g. America/Los_Angeles

const utcDate = zonedTimeToUtc(date, timeZone) // In June 10am in Los Angeles is 5pm UTC

postToServer(utcDate.toISOString(), timeZone) // post 2014-06-25T17:00:00.000Z, America/Los_Angeles

utcToZonedTime

Get a date/time in the local time of any time zone from UTC time

utcToZonedTime(date: Date|Number|String, timeZone: String): Date

Say the server provided a UTC date/time and a time zone which should be used as initial values for the above form. The date/time picker will take a Date input which will be in the user's local time zone, but the date value must be that of the target time zone.

import { utcToZonedTime } from 'date-fns-tz'

const { isoDate, timeZone } = fetchInitialValues() // 2014-06-25T10:00:00.000Z, America/New_York

const date = utcToZonedTime(isoDate, timeZone) // In June 10am UTC is 6am in New York (-04:00)

renderDatePicker(date) // 2014-06-25 06:00:00 (in the system time zone)
renderTimeZoneSelect(timeZone) // America/New_York

getTimezoneOffset

Gets the offset in milliseconds between the time zone and UTC time

getTimezoneOffset(timeZone: String, date: Date|Number): number

Returns the time zone offset from UTC time in milliseconds for IANA time zones as well as other time zone offset string formats.

For time zones where daylight savings time is applicable a Date should be passed on the second parameter to ensure the offset correctly accounts for DST at that time of year. When omitted, the current date is used.

import { getTimezoneOffset } from 'date-fns-tz'

const result = getTimezoneOffset('-07:00')
//=> -18000000 (-7 * 60 * 60 * 1000)
const result = getTimezoneOffset('Africa/Johannesburg')
//=> 7200000 (2 * 60 * 60 * 1000)
const result = getTimezoneOffset('America/New_York', new Date(2016, 0, 1))
//=> -18000000 (-5 * 60 * 60 * 1000)
const result = getTimezoneOffset('America/New_York', new Date(2016, 6, 1))
//=> -14400000 (-4 * 60 * 60 * 1000)

Time Zone Formatting

format

The format function exported from this library extends date-fns/format with full time zone support for:

  • The z..zzz Unicode tokens: short specific non-location format
  • The zzzz Unicode token: long specific non-location format

When using those tokens with date-fns/format it falls back to GMT timezones, and always uses the local system timezone. For example zzz in New York would return GMT-4 instead of the desired EST, whereas this extended format function will return the latter.

To format a date to a string showing time for a specific time zone, which can be different from the system time zone, the format function can be combined with utcToZonedTime as shown in the example below. To clarify, the format function will never change the underlying date, it must be changed to a zoned time before passing it to format.

Since a zoned time Date instance cannot convey the time zone information to the format function it is necessary to pass the same timeZone value as an option on the third argument of format. When using this option the z..zzzz, x..xxxxx, X..XXXXX and O..OOO tokens will all print the provided time zone rather than the system time zone.

import { format, utcToZonedTime } from 'date-fns-tz'

const date = new Date('2014-10-25T10:46:20Z')
const nyTimeZone = 'America/New_York'
const parisTimeZone = 'Europe/Paris'

const nyDate = utcToZonedTime(date, nyTimeZone)
const parisDate = utcToZonedTime(date, parisTimeZone)

format(nyDate, 'yyyy-MM-dd HH:mm:ssXXX', { timeZone: 'America/New_York' }) // 2014-10-25 06:46:20-04:00
format(nyDate, 'yyyy-MM-dd HH:mm:ss zzz', { timeZone: 'America/New_York' }) // 2014-10-25 06:46:20 EST
format(parisDate, 'yyyy-MM-dd HH:mm:ss zzz', { timeZone: 'Europe/Paris' }) // 2014-10-25 10:46:20 GMT+2

// The time zone name is generated by the Intl API which works best when a locale is also provided
import enGB from 'date-fns/locale/en-GB'

format(parisDate, 'yyyy-MM-dd HH:mm:ss zzz', {
  timeZone: 'Europe/Paris',
  locale: enGB,
})
// 2014-10-25 10:46:20 CEST
format(parisDate, 'yyyy-MM-dd HH:mm:ss zzzz', {
  timeZone: 'Europe/Paris',
  locale: enGB,
})
// 2014-10-25 10:46:20 Central European Summer Time

toDate

The toDate function can be used to create a zoned Date from a string containing an offset or IANA time zone, or by providing the timeZone option.

import { toDate, format } from 'date-fns-tz'

// Offsets in the date string work as usual and take precedence
const parisDate = toDate('2014-10-25T13:46:20+02:00')
format(parisDate, 'yyyy-MM-dd HH:mm:ssZ', { timeZone: 'Europe/Paris' }) // 2014-10-25 13:46:20+02:00

// Since toDate simply clones a Date instance timeZone option is effectively ignored in this case
const date = new Date('2014-10-25T13:46:20Z')
const clonedDate = toDate(date, { timeZone: 'Europe/Paris' })
assert(date.valueOf() === clonedDate.valueOf())

// When there is no offset in the date string the timeZone property is used
const bangkokDate = toDate('2014-10-25T13:46:20', { timeZone: 'Asia/Bangkok' })
format(bangkokDate, 'yyyy-MM-dd HH:mm:ssZ', { timeZone: 'Asia/Bangkok' }) // 2014-10-25 13:46:20+07:00

const nyDate = toDate('2014-10-25T13:46:20 America/New_York')
format(nyDate, 'yyyy-MM-dd HH:mm:ssZ', { timeZone: 'America/New_York' }) // 2014-10-25 13:46:20-04:00

Note: Since the Intl API does not provide a way to parse long or short time zone names the parse function cannot be supported using this approach.

Usage with Node.js

Node.js supports the Intl API. From v13 Node.js ships with full ICU data included in the binary, however the current LTS version 12.14 is still built with the small-icu flag and only contains ICU data for the en-US locale. To use this library with Node.js 12 and any locale other than en-US it should be run with ICU data provided at runtime.

Credit

The idea of using the Intl API for time zone support was inspired by the Luxon library.

The initial port of the idea into date-fns was done by @benmccan in date-fns/#676.

License

MIT © Marnus Weststrate

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].