Weird Timezone Issue with Pytz

Weird timezone issue with pytz

Time zones and offsets change over the years. The default zone name and offset delivered when pytz creates a timezone object are the earliest ones available for that zone, and sometimes they can seem kind of strange. When you use localize to attach the zone to a date, the proper zone name and offset are substituted. Simply using the datetime constructor to attach the zone to the date doesn't allow it to adjust properly.

pytz timezone DST issue

America/New_York is not the same as EST. The former adjusts for the daylight saving shifts. The latter is fixed to be Eastern Standard Time.
Use:

est = pytz.timezone('EST')

pytz giving wrong timezone offset for 'Africa/Khartoum'

I cannot reproduce the example for datetime.datetime.now. pytz also shows the correct UTC offset change in 2017 for the timezone 'Africa/Khartoum'. However, you need to use the localize method (see e.g. here).

import datetime
import pytz

tz = pytz.timezone('Africa/Khartoum')

# correct UTC offset for "now":
tz_offset = tz.localize(datetime.datetime.now()).strftime('%z')
print(tz_offset)
# +0200

# also correct UTC offset around 1st Nov 2017:
tz_offset = tz.localize(datetime.datetime(2017,10,31)).strftime('%z')
print(tz_offset)
# +0300
tz_offset = tz.localize(datetime.datetime(2017,11,1)).strftime('%z')
print(tz_offset)
# +0200

If you don't localize, you only get the local mean time. With dateutil, you would not have to localize and could implement the timezone directly:

import dateutil
tz = dateutil.tz.gettz('Africa/Khartoum')
tz_offset = datetime.datetime(2017,10,31, tzinfo=tz).strftime('%z')
print(tz_offset)
# +0300
tz_offset = datetime.datetime(2017,11,1, tzinfo=tz).strftime('%z')
print(tz_offset)
# +0200

Timezone Timestamp Weirdness

You need to localize correctly - with pytz's timezone objects, setting tzinfo directly when creating the datetime object is not the right way. It's in the docs:

This library only supports two ways of building a localized time. The first is to use the localize() method provided by the pytz library.

and

The second way of building a localized time is by converting an existing localized time using the standard astimezone() method


On the other hand, if you happen to use Python 3.9+, you can use the zoneinfo module from the standard lib to make you life easier - see the docs / using-zoneinfo or example usage here.

Python datetime object show wrong timezone offset

See: http://bytes.com/topic/python/answers/676275-pytz-giving-incorrect-offset-timezone

In the comments, someone proposes to use tzinfo.localize() instead of the datetime constructor, which does the trick.

>>> tz = timezone('Asia/Kolkata')
>>> dt = tz.localize(datetime.datetime(2011, 6, 20, 0, 0, 0, 0))
>>> dt
datetime.datetime(2011, 6, 20, 0, 0, tzinfo=<DstTzInfo 'Asia/Kolkata' IST+5:30:00 STD>)

UPDATE: Actually, the official pytz website states that you should always use localize or astimezone instead of passing a timezone object to datetime.datetime.



Related Topics



Leave a reply



Submit