← more articles

GNU Date - timezone conversions

When it is Monday, Sep 18th 2017, 6am in Sydney (Australia),
what is the time in Toronto (Canada)?

GNU date can answer that question:

$ TZ=America/Toronto date -d 'TZ="Australia/Sydney" 2017-09-18 6am'
Sun Sep 17 16:00:00 EDT 2017

In Toronto, it will be Sunday, Sep 17th, 4pm (16:00).


Use the following syntax to convert time and dates between time zones:

 output timezone                 input timezone        input date/time
------------------             --------------------    ---------------

TZ=America/Toronto    date -d 'TZ="Australia/Sydney"   2017-09-18 6am'


Below are more details, examples and use cases.


Current time in a different time zone

What is the current time in Tokyo (Japan)?

$ TZ=Asia/Tokyo date
Mon Sep 18 06:46:04 JST 2017         # Your results will vary based on the current time

To print the current time and date in a different time zone, simply set the TZ environment variable.

Convert a different timezone to local time

When it’s 7am in Singapore, what is the local time here?

 $ date -d 'TZ="Asia/Singapore" 2017-09-17 7am'
 Sat Sep 16 17:00:00 MDT 2017                    # Your result will vary based on your local timezone

To convert another timezone to your local time zone, set the input TZ variable inside the -d date string argument.



Syntax Gotchas

  1. The TZ environment variable should contain a valid time zone name. See next section to find out the time zones available on your system.

  2. The second TZ definition (the input timezone) must be surrounded by double-quotes. Without them, date will fail to parse the time zone string:

    $ TZ=America/Toronto date -d 'TZ=Australia/Sydney 2017-09-18 6am'    # missing double-quotes around Australia/Sydney
    date: invalid date `TZ=Australia/Sydney 2017-09-18 6am'
    

    The argument to the -d parameter is a string, and must be quoted. If quoting the entire parameter with double-quotes, be sure to escape the inner quotes:

    $ TZ=America/Toronto date -d "TZ=\"Australia/Sydney\" 2017-09-18 6am"
    Sun Sep 17 16:00:00 EDT 2017
    
  3. Invalid or non-existing timezone names are silently ignored and treated as UTC (time zone 00:00, similar to GMT+0). This behaviour is required by POSIX. When getting unexpected results, be sure to check for timezone typos:

    $ TZ=America/newyork date         ## 'newyork' is not a valid timezone name
    Sun Sep 17 21:58:49 America 2017  ## result is incorrect
    
    $ TZ=America/New_York date        ## 'New_York' is the correct timezone name,
    Sun Sep 17 17:58:55 EDT 2017      ## Using the file /usr/share/zoneinfo/America/New_York
    
  4. These timezone conversion strings require GNU date. GNU date is installed by default on most GNU/Linux distributions (e.g. Debian,Ubuntu,CentOS,RedHat,Fedora,Gentoo). It is not available by default on Mac OS X, FreeBSD, OpenBSD, etc. To install GNU date on MacOS X, consider using HomeBrew.

Available Time zones

On most Unix systems, the available time zones are stored as files in the /usr/share/zoneinfo directory:

$ ls /usr/share/zoneinfo/
Africa      Egypt      Hongkong           Mexico      ROC
America     Eire       HST                MST         ROK
Antarctica  EST        Iceland            MST7MDT     Singapore
Arctic      EST5EDT    Indian             Navajo      SystemV
Asia        Etc        Iran               NZ          Turkey
Atlantic    Europe     iso3166.tab        NZ-CHAT     UCT
Australia   Factory    Israel             Pacific     Universal
Brazil      GB         Jamaica            Poland      US
Canada      GB-Eire    Japan              Portugal    UTC
CET         GMT        Kwajalein          posix       WET
Chile       GMT0       leap-seconds.list  posixrules  W-SU
CST6CDT     GMT-0      Libya              PRC         Zulu
Cuba        GMT+0

Inside each sub-directory (e.g. America) are a list of locations which can be used as the timezone name:

$ ls /usr/share/zoneinfo/America/
Adak
Anchorage
Anguilla
Antigua
Araguaina
Argentina
Aruba
...

These files originate from the TZ Database maintained by Paul Eggert.

Timezone abbreviations (e.g. “EST”, “EDT”) are not recommended as they are ambiguous between different regions:

$ TZ=Asia/Tokyo date -d '2017-11-05 6am EST'  # NOT recommended
Sun Nov  5 20:00:00 JST 2017

For example, “IST” could mean Irish Standard Time (UTC+1) or India Standard Time (UTC+5:30).

Additionally, using timezone abbreviations requires you to know if a region is using daylight saving time (DST) or not.

For example, on November 4th, 2015, was New York using EST (Eastern Standard Time, UTC-5) or EDT (Eastern Daylight saving time, UTC-4)? (For the answer, see here).

Using the appropriate timezone location (e.g. America/New-York) instead of EDT/EST ensures the correct daylight-saving-time setting is used (as the TZ database is routinely updated with the latest up-to-date information for each country).


Explicit zone hours are not recommended, as they ignore possible daylight-saving-time changes:

$ TZ=UTC4 date -d '2017-09-16 06:00+10'  # NOT recommended
Fri Sep 15 16:00:00 UTC 2017

While the above syntax is valid, it is not recommended. It converts the input date ‘2017-09-16 6am in timezone UTC+10’ (matching Sydney, Australia) to UTC-4 (matching Toronto, Canada), and returns the correct time (4pm/16:00 in Toronto). This conversion is correct only while Sydney uses Australian Eastern Standard Time (AEST) and Ontario uses Eastern Daylight Time (EDT).

Using explicit timezone hours ignores daylight saving changes. Daylight saving time changes are quite fluid, and many time depend on local politics. For example, the Canadian province Alberta is considering to do away with annual daylight saving time changes completely.

If such changes were to happen, the TZ database will be updated accordingly and using TZ=America/Edmonton timezone will use the correct value (depending on the year and date, including past years which still used daylight saving time).

More to follow

Stay tuned for more about gnu date:

  • Using date in shell scripting and pipeline automation
  • Date artihmetics
  • The new date --debug option



Follow me at @AGordonX for more articles (questions and topic requests are welcomed).

← more articles