How do you convert a timestamp into a datetime in python with the correct timezone? -
you naively expect work:
import pytz datetime import datetime def tz_datetime_from_timestamp(timestamp): """convert timestamp datetime """ tz = pytz.timezone('australia/perth') server_time = datetime.utcnow() delta = tz.utcoffset(server_time) value = datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz) return value + delta print tz_datetime_from_timestamp(1416387060)
and convert timestamp 1416387060 wed nov 19 16:51:00 2014 gmt+8:00.
...but not. prints:
2014-11-19 16:51:00+07:43
the timezone of australia/perth not gmt+7:43.
it gmt+8:00. unequivocally stated on australian government website http://www.australia.gov.au/about-australia/our-country/time:
awst equal coordinated universal time plus 8 hours (utc +8).
so, heck pytz pulling 7.43 from?
well, turns out pytz pulls data http://www.iana.org/time-zones time zone database, , database states:
# western australia # # rule name type in on @ save letter/s rule aw 1974 - oct lastsun 2:00s 1:00 d rule aw 1975 - mar sun>=1 2:00s 0 s rule aw 1983 - oct lastsun 2:00s 1:00 d rule aw 1984 - mar sun>=1 2:00s 0 s rule aw 1991 - nov 17 2:00s 1:00 d rule aw 1992 - mar sun>=1 2:00s 0 s rule aw 2006 - dec 3 2:00s 1:00 d rule aw 2007 2009 - mar lastsun 2:00s 0 s rule aw 2007 2008 - oct lastsun 2:00s 1:00 d zone australia/perth 7:43:24 - lmt 1895 dec 8:00 aus aw%st 1943 jul 8:00 aw aw%st
well. that's great.... it's incorrect.
...and python, result, unfortunately.
the olson time database full of values like (4 hours , 15 minutes, 5 hours , 20 minutes, etc.). totally weird.
technically don't care exact timezone is, long universally consistent; unfortunately it's not. making (for example) api call , passing timezone across remote service (correctly) uses gmt+8 timezone results in discrepancy between values when timezones converted utc processing.
ie. absolutely clear, these 2 values different times when converted utc:
- wed nov 19 16:51:00 2014 gmt+8:00
- wed nov 19 16:51:00 2014 gmt+7:43
irritatingly:
server_time = datetime.utcnow() delta = tz.utcoffset(server_time) print(delta)
yields:
8:00:00
so pytz internally does know correct timezone offset. generates output wrong value attached.
so, finally: how generate datetime correct timezone attached it?
the long story short, pytz defaults incorrect timezone, , datetime.replace() doesn't perform conversions:
import pytz datetime import datetime fmt = '%y-%m-%d %h:%m:%s %z%z' tz = pytz.timezone('australia/perth') timestamp = 1416387060 print(tz) # correct way utctime = pytz.utc.localize(datetime.utcfromtimestamp(timestamp)) print(utctime.strftime(fmt)) astimezone = utctime.astimezone(tz) print(astimezone.strftime(fmt)) localtime = tz.normalize(astimezone) print(localtime.strftime(fmt)) # incorrect way incorrect = datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz) print(incorrect.strftime(fmt))
you can read more in various bugs in pytz in discussed:
In present time finding and trusting any online service can prove to be a decision of loss. This is why just trust on highly reputed assignment service we offer through our site. ContentRage
ReplyDelete