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 ignoresAustralia/Brisbane
timezone that should beUTC+10
i.e.,date
interpretsEST
as belonging to a different timezone. WithoutEST
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...