> On 10 Feb 2020, at 23:01, Python <pyt...@bladeshadow.org> wrote: > > As best I can tell, Python has no means to make use of the system's > timezone info. In order to make datetime "timezone aware", you need > to manually create a subclass of datetime.tzinfo, whose methods return > the correct values for the timezone you care about. In the general > case, this is hard, but since the timezone my dates are in is always > GMT, it's no problem: > > class GMT(datetime.tzinfo): > def utcoffset(self, dt): > return datetime.timedelta(hours=0) > def dst(self, dt): > return datetime.timedelta(minutes=0) > def tzname(self, dt): > return "GMT" > > Now, you can instantiate a datetime.datetime object with the times you > want, and pass an instance of this class as the tzinfo argument to the > constructor. Also no problem:
>>>> dt = datetime.datetime(2020, 1, 31, 1, 30, 45, 987654, GMT()) >>>> dt > datetime.datetime(2020, 1, 31, 1, 30, 45, 987654, tzinfo=<__main__.GMT object > at 0x7f9084e2add0>) >>>> print dt > 2020-01-31 01:30:45.987654+00:00 > > Note the tzinfo object, and the +00:00 indicating this is indeed in > GMT. If you create a "naive" datetime object, you don't get that: > >>>> xy = datetime.datetime(2020, 1, 31, 1, 30, 45, 987654) >>>> xy > datetime.datetime(2020, 1, 31, 1, 30, 45, 987654) >>>> print xy > 2020-01-31 01:30:45.987654 > > > So far, so good. However, when you go to use this object, the time it > represents is in fact wrong. For example: > >>>> print dt.strftime("%s") > 1580452245 > > Using the date command, we can easily see that it is incorrect: > > # Ask for UTC, gives the wrong time > $ date -u -d "@1580452245" > Fri Jan 31 06:30:45 UTC 2020 > > # Ask for local time, gives the time I specified... which should have > # been in GMT, but is in my local timezone > $ date -d "@1580452245" > Fri Jan 31 01:30:45 EST 2020 > > And the correct value should have been: > $ date -d "2020-01-31 1:30:45 GMT" +%s > 1580434245 > > Same results under Python2.7 or Python3. > > :( :( :( > > I suspect this is because the underlying implementation uses > strftime() which takes struct tm, which has no field to contain the > timezone info, and does not do the necessary conversion before handing > it off. I'm not sure what the date command is doing differently, but > it clearly is able to get the correct answer. > > Does Python have an alternative way to do the above, with correct > results? I found that there are two useful PyPi packages to help with time zones. pytz and tzlocal. Here is a piece of code that I use to be timezone aware for UTC and the local time zone. It works for Windows, macOS and unix thanks. import datetime import pytz import tzlocal def utcDatetime( timestamp ): return pytz.utc.localize( datetime.datetime.utcfromtimestamp( timestamp ) ) def localDatetime( datetime_or_timestamp ): if type(datetime_or_timestamp) in (int, float): dt = utcDatetime( datetime_or_timestamp ) else: dt = datetime_or_timestamp local_timezone = tzlocal.get_localzone() local_dt = dt.astimezone( local_timezone ) return local_dt Barry > > Thanks > > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list