Tuesday, April 6, 2010

Converting time between timezones in Linux

People working with systems that are located in different timezones are always faced with the problem of converting time between timezones. On GNU Linux systems ( and most other POSIX OSs) you can manipulate the TZ environment variable to achieve this.

Generally on Linux systems, the timezone information is kept in the file /etc/localtime. This file is usually a softlink to an appropriate zone file under the location "/usr/share/zoneinfo/".

safeer@penguinpower:~$ ls -l /usr/share/zoneinfo/
drwxr-xr-x 2 root root 4096 2010-02-21 01:46 Africa
drwxr-xr-x 6 root root 12288 2010-02-21 01:46 America
drwxr-xr-x 2 root root 4096 2010-02-21 01:46 Antarctica
.............................
-rw-r--r-- 1 root root 2294 2010-01-03 01:38 EST5EDT
drwxr-xr-x 2 root root 4096 2010-02-21 01:46 Etc
drwxr-xr-x 2 root root 4096 2010-02-21 01:46 Europe
.............................
-rw-r--r-- 1 root root 118 2010-01-03 01:38 UTC
-rw-r--r-- 1 root root 1873 2010-01-03 01:38 WET
-rw-r--r-- 1 root root 2194 2010-01-03 01:38 W-SU
-rw-r--r-- 1 root root 18896 2009-12-12 20:27 zone.tab
-rw-r--r-- 1 root root 118 2010-01-03 01:38 Zulu

Some of these are directories which have timezone files under them. For eg, the directory Asia contains zone files for all the countries ( or their capital/important cities) in Asia, including India,China,Pakistan etc....

safeer@penguinpower:~$ ls -l /usr/share/zoneinfo/Asia/
-rw-r--r-- 1 root root 157 2010-01-03 01:38 Aden
-rw-r--r-- 1 root root 922 2010-01-03 01:38 Almaty
-rw-r--r-- 1 root root 8504 2010-01-03 01:38 Amman
............................
-rw-r--r-- 2 root root 657 2010-01-03 01:38 Ashgabat
-rw-r--r-- 2 root root 657 2010-01-03 01:38 Ashkhabad
-rw-r--r-- 1 root root 962 2010-01-03 01:38 Baghdad
...............
-rw-r--r-- 1 root root 1929 2010-01-03 01:38 Vladivostok
-rw-r--r-- 1 root root 1914 2010-01-03 01:38 Yakutsk
-rw-r--r-- 1 root root 2000 2010-01-03 01:38 Yekaterinburg
-rw-r--r-- 1 root root 2012 2010-01-03 01:38 Yerevan

We are going to use this directory structure for setting the TZ variable. The value of TZ variable will be the relative path of the desired timezone file with reference to "/usr/share/zoneinfo". As an example, I am going to change my system time to Singapore time.

safeer@penguinpower:~$ date
Tue Apr 6 00:44:54 IST 2010

safeer@penguinpower:~$ export TZ=Asia/Singapore

safeer@penguinpower:~$ date

Tue Apr 6 03:15:37 SGT 2010


What if you don't want to set the TZ variable but just need to see the current Singapore time?

safeer@penguinpower:~$ date
Tue Apr 6 00:48:07 IST 2010

safeer@penguinpower:~$ TZ=Asia/Singapore date

Tue Apr 6 03:18:12 SGT 2010

safeer@penguinpower:~$ date

Tue Apr 6 00:48:16 IST 2010


Here the value "Asia/Singapore" will be applicable only to the command 'date' during its execution.

We are going to use this, along with a feature of 'date' command for converting between different timezones.

Now our machine's timezone is India Standard Time (IST - Asia/Calcutta ), we need to see what will be the time in India when the Singapore time is 2:24 PM on a particular day.

safeer@penguinpower:~$ date -d 'TZ="Asia/Singapore" 2010-03-10 14:24:00'
Wed Mar 10 11:54:00 IST 2010


This shows that SGT is two and half hours ahead of IST. The -d option allows specifying a TZ variable which helped us in getting this answer. Now suppose that you want to see what will be the time in Dubai when it is 2.30 PM in Singapore. But our local timezone is in IST and should not be changed.

The way to do this is, set the TZ variable to Dubai timezone just for the particular date command. Here is how we can do it.

safeer@penguinpower:~$ TZ=Asia/Dubai date -d 'TZ="Asia/Singapore" 2010-03-10 14:24:00'
Wed Mar 10 10:24:00 GST 2010

This shows us that, Dubai time ( GST - Gulf Standard Time) is 4 hours behind Singapore time (SGT).

So the general syntax for conversion can be summarized as below:

TZ=$TO_TIMEZONE date -d 'TZ="$FROM_TIMEZONE" YYYY-MM-DD HH:MM:SS'
Where $FROM_TIMEZONE is the timezone from which the conversion should be done and $TO_TIMEZONE is the timezone to which the date should be converted. Here:

TO_TIMEZONE=Asia/Calcutta, FROM_TIMEZONE=Asia/Singapore


If you regularly do date conversions you can write a wrapper script around this command.

To learn more about TZ variable, please visit TZ page on GNU website

No comments:

Post a Comment