Python datetime strptime () and strftime (): how to save timezone information

See the following code:

import datetime import pytz fmt = '%Y-%m-%d %H:%M:%S %Z' d = datetime.datetime.now(pytz.timezone("America/New_York")) d_string = d.strftime(fmt) d2 = datetime.datetime.strptime(d_string, fmt) print d_string print d2.strftime(fmt) 

output

 2013-02-07 17:42:31 EST 2013-02-07 17:42:31 

Time zone information was simply lost in translation.

If I switch '% Z' to '% z', I get

 ValueError: 'z' is a bad directive in format '%Y-%m-%d %H:%M:%S %z' 

I know I can use python-dateutil , but I just found this bizzare, that I cannot achieve this simple function in datetime and have to introduce more dependencies?

+47
python datetime python-datetime python-dateutil
Feb 07 '13 at 22:46
source share
3 answers

Part of the problem here is that the strings commonly used to represent time zones are not really unique. “EST” only means “America / New_York” for people in North America. This is a limitation in the C API, and the Python solution is to add all tz functions to any future version at any time if someone wants to write PEP.

You can format and parse the time zone as an offset, but this loses daylight saving time (for example, you cannot distinguish between America / Phoenix and America / Los_Angeles in summer). You can format the time zone as an abbreviation of 3 letters, but you cannot cancel it.

If you want something fuzzy and ambiguous, but usually what you want, you need a third-party library like dateutil .

If you want something really unambiguous, just add the actual name tz to the local datetime string and split it at the other end:

 d = datetime.datetime.now(pytz.timezone("America/New_York")) dtz_string = d.strftime(fmt) + ' ' + "America/New_York" d_string, tz_string = dtz_string.rsplit(' ', 1) d2 = datetime.datetime.strptime(d_string, fmt) tz2 = pytz.timezone(tz_string) print dtz_string print d2.strftime(fmt) + ' ' + tz_string 

Or ... halfway between the two, you are already using the pytz library, which can parse (according to some arbitrary, but well-defined ambiguity rules) formats such as "EST". So, if you really want this, you can leave %Z on the format side, then pull it out and pytz.timezone() with pytz.timezone() before passing the rest to strptime .

+30
Feb 07 '13 at 23:55
source share

Unfortunately, strptime() can only process the time zone configured by your OS, and then only as a temporary offset. From the doc:

Support for the %Z directive is based on the values ​​contained in tzname and whether the daylight value is true. Because of this, it depends on the platform, with the exception of the recognition of UTC and GMT, which are always known (and are considered hours excluding daylight saving time).

strftime() does not officially support %Z

Delayed by python-dateutil to support timezone parsing, I'm afraid.

+10
Feb 07 '13 at 23:43
source share

Here is my answer in Python 2.7

Print current time with time zone

 from datetime import datetime import tzlocal # pip install tzlocal print datetime.now(tzlocal.get_localzone()).strftime("%Y-%m-%d %H:%M:%S %z") 

Print current time with a specific time zone

 from datetime import datetime import pytz # pip install pytz print datetime.now(pytz.timezone('Asia/Taipei')).strftime("%Y-%m-%d %H:%M:%S %z") 

It will print something like

 2017-08-10 20:46:24 +0800 
+1
Aug 10 '17 at 13:07 on
source share



All Articles