Timezones

The Date Math package includes a timezone database and utilities for working with dates in different timezones.

Basics

The JavaScript Date Object

In JavaScript, the Date object represents a single moment in time that is measured in milliseconds starting on 01 January, 1970 UTC. The Date objects are always created by using the current browser timezone offset.

The following example demonstrates how to construct a new Date object for a particular UTC date.

// 22 Oct 2018 12:00:00 GMT
const date = new Date(2018, 9, 22, 15, 0, 0);

The following result in the browser console shows that your current timezone offset is already applied.

console.log(date.toString());
> Mon Oct 22 2018 15:00:00 GMT+0300 (EEST)

JSON Serialization

The JSON.stringify and JSON.parse methods serialize dates as UTC. For example, if you convert the previously created JavaScript Date object to JSON, the output is the '"2014-02-01T10:00:00.000Z"' UTC date that was formatted by using the ISO8601 standard. The JSON serialization methods guarantee that regardless of their particular timezone offsets, the exact moment in time will be represented both in the browser and on the server.

Loading Timezone Data

The Date Math package enables you to load a timezone data for a specific city, continent, or for the whole world which you can use to add or remove a specific time offset from the JavaScript Date value.

  • Before you use the timezone conversion methods, pre-load all timezone details.
  • The Etc/UTC timezone is loaded by default.
  • List of time zones

To import the pre-built timezone scripts which are generated from the Time Zone Database from the package list, use the following example:

// Load timezone data for a specific time zone
import '@progress/kendo-date-math/tz/Europe/Sofia';

// Load the timezone for a region
// The uncompressed file size is around ~150kB
import '@progress/kendo-date-math/tz/regions/Europe';

// Load all available timezone data
// Warning: The uncompressed file size is over 600kB
import '@progress/kendo-date-math/tz/all'

Timezone Calculations

To create a date in a different timezone and perform calculations, create an instance of the ZonedDate class.

While ZonedDate behaves similarly to a regular Date, it is immutable and the set* methods throw errors.

Converting Local Dates

You can create a date in a different timezone which represents the same moment in time as a local date by using the fromLocalDate (date, timezone) method.

The following example demonstrates how to create a date in a different timezone and output it by using toString().

import React from 'react';
import ReactDOM from 'react-dom';

import { timezoneNames, ZonedDate } from '@progress/kendo-date-math';
import '@progress/kendo-date-math/tz/all';

const timezones =
  timezoneNames()
  .filter(l => l.indexOf('/') > -1)
  .sort((a, b) => a.localeCompare(b));

class App extends React.Component {
    interval;
    state = {
        timezone: 'Europe/Sofia',
        date: null,
        result: null
    };

    componentDidMount() {
        this.tick();
        this.interval = setInterval(() => this.tick(), 1000);
    }

    componentWillUnmount() {
        clearInterval(this.interval);
    }

    tick = () => {
        const date = new Date();
        const result = ZonedDate.fromLocalDate(date, this.state.timezone);
        this.setState({ date, result });
    }

    handleTimezoneChange = (event) => {
        this.setState({ timezone: event.target.value });
    }

    render() {
        const { result, date } = this.state;
        return (
            <React.Fragment>
                <div className="row example-config">
                    <div className="col-xs-12 example-col">
                        <p>Current Universal Coordinated Time</p>
                        {date && date.toGMTString()}
                    </div>
                </div>
                <div className="row example-config">
                    <div className="col-xs-12 example-col">
                        <p>
                            Local time in
                            <select onChange={this.handleTimezoneChange} value={this.state.timezone}>
                                {timezones.map((zone, i) => <option key={i}>{zone}</option>)}
                            </select>
                        </p>
                        {result && result.toString()}
                    </div>
                </div>
            </React.Fragment>
        );
    }
}

ReactDOM.render(
    <App />,
    document.querySelector('my-app')
);

Converting Dates with Timezones

You can create a date in any time zone by using the fromUTCDate (date, timezone) method. fromUTCDate takes a UTC date but treats it as a date in the set timezone.

import { ZonedDate } from '@progress/kendo-date-math';
import '@progress/kendo-date-math/tz/America/New_York';

// Note the "Z" suffix for UTC dates
const date = new Date('2018-03-12T18:00:00Z');
const tzDate = ZonedDate.fromUTCDate(date, 'America/New_York');

// The local date represents the same moment in time as the ZonedDate:
// `2018-03-12T22:00:00.000Z`
console.log(tzDate.toLocalDate().toISOString());

Why UTC dates instead of normal? The Date object will constrain values according to the local time zone Daylight Saving Time rules. This means that not all dates are representable as local dates. Even worse, they'll be silently corrected to the first valid date. This does not apply to the UTC part of the dates, making them a safe choice for representing arbitrary dates.

Converting between Timezones

To convert between timezones without creating intermediate local dates, use the toTimezone (timezone) method.

import { ZonedDate } from '@progress/kendo-date-math';
import '@progress/kendo-date-math/tz/America/New_York';
import '@progress/kendo-date-math/tz/America/Los_Angeles';

// Note the "Z" suffix for UTC dates
const date = new Date('2018-03-12T22:00:00Z');

const tzDate = ZonedDate.fromLocalDate(date, 'America/New_York');
const result = tzDate.toTimezone('America/Los_Angeles');

// Regardless of the browser time zone
// the output would be: '2018-03-12T15:00:00.000Z'
console.log(result.toUTCDate());

Timezone Details

The timezone scripts also provide human readable names for the Internet Assigned Numbers Authority (IANA) timezones and grouped timezone names—for example, (GMT+02) Helsinki, Sofia....

Listing All Timezones

To list all loaded timezone scripts, use the timezoneNames function.

import '@progress/kendo-date-math/tz/America/New_York';
import '@progress/kendo-date-math/tz/Europe/Sofia';

import { timezoneNames } from '@progress/kendo-date-math';

const list = timezoneNames();

console.log(list); //['America/New_York', 'Europe/Sofia']

Getting Specific Timezone Groups

To get all IANA timezones that are listed under a specific group, use the zonesPerGroup method.

import '@progress/kendo-date-math/tz/Europe/Amsterdam';
import '@progress/kendo-date-math/tz/Europe/Berlin';
import '@progress/kendo-date-math/tz/Europe/Sofia';

import { zonesPerGroup } from '@progress/kendo-date-math';

const zonesForGMT1 = zonesPerGroup('(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna');

console.log(zonesForGMT1); //['Europe/Amsterdam', 'Europe/Berlin']
 /