linux convert time(for different timezones) to UTC

Solution 1:

Update: the result with the recent tz database is different: EST yields the same utc offset for a given date (compare with the previous result). Though it does not affect the general conclusion that different timezones may use the same abbreviation and therefore the same abbreviation may correspond to different utc offsets. See Parsing date/time string with timezone abbreviated name in Python?


Abbreviated timezone names such as EST may be ambiguous.

Example

#!/bin/sh
for tz in Australia/Brisbane Australia/Sydney America/New_York
do date -u -d"TZ=\":$tz\" Tue Jan  4 11:30:23 EST 2013"
done

Output

Fri Jan  4 16:30:23 UTC 2013
Fri Jan  4 00:30:23 UTC 2013
Fri Jan  4 16:30:23 UTC 2013

Two things:

  • the date string may be interpreted as different moments in time depending on the timezone used

  • date silently ignores Australia/Brisbane timezone that should be UTC+10 i.e., date interprets EST as belonging to a different timezone. Without EST it produces correct time:

      $ date -u -d 'TZ=":Australia/Brisbane" Tue Jan  4 11:30:23 2013'
      Fri Jan  4 01:30:23 UTC 2013
    

To find all possible UTC times for given time and timezone abbreviation e.g., for 'Tue Jan 4 11:30:23 EST 2013':

#!/usr/bin/env python
from collections import defaultdict
from datetime import datetime
import pytz # $ sudo apt-get install python-tz
            # or if you can't install system-wide
            # $ pip install --user pytz

## Tue Dec  14 10:30:23 PST 2012
#naive_dt, tzname = datetime(2012, 12, 14, 10, 30, 23), 'PST'
## -> Fri Dec 14 18:30:23 2012 UTC

# Tue Jan  4 11:30:23 EST 2013
naive_dt, tzname = datetime(2013, 1, 4, 11, 30, 23), 'EST'
# Fri Jan  4 01:30:23 2013 UTC
# Fri Jan  4 00:30:23 2013 UTC
# Fri Jan  4 16:30:23 2013 UTC
# ambiguous
 
utc_times = defaultdict(list)
for zone in pytz.all_timezones:
    dt = pytz.timezone(zone).localize(naive_dt, is_dst=None)
    if dt.tzname() == tzname: # same timezone abbreviation
        utc_times[dt.astimezone(pytz.utc)].append(zone)

for utc_dt, timezones in utc_times.items():
    print("%s:\n\t%s" % (utc_dt.strftime('%c %Z'), '\n\t'.join(timezones)))

Output

All Tue Jan 4 11:30:23 EST 2013 interpretations as UTC with corresponding timezone names:

Fri Jan  4 01:30:23 2013 UTC:
    Australia/Brisbane
    Australia/Lindeman
    Australia/Queensland
Fri Jan  4 00:30:23 2013 UTC:
    Australia/ACT
    Australia/Canberra
    Australia/Currie
    Australia/Hobart
    Australia/Melbourne
    Australia/NSW
    Australia/Sydney
    Australia/Tasmania
    Australia/Victoria
Fri Jan  4 16:30:23 2013 UTC:
    America/Atikokan
    America/Cayman
    America/Coral_Harbour
    America/Detroit
    ...
    America/New_York
    ...
    America/Toronto
    Canada/Eastern
    EST
    EST5EDT
    Jamaica
    US/East-Indiana
    US/Eastern
    US/Michigan

Solution 2:

date -u -d "Tue Dec 14 10:30:23 PST 2012" reports Fri Dec 14 18:30:23 UTC 2012. The discrepancy is because Dec 14 2012 is in fact a Friday, not a Tuesday. It probably works better with valid input...