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
Downloading a Picture via Urllib and Python
Django Multivaluedictkeyerror Error, How to Deal with It
How to Enable Cors on Django Rest Framework
Order' of Unordered Python Sets
Slice 2D Array into Smaller 2D Arrays
Staleelementexception When Iterating with Python
How to Use a Dot "." to Access Members of Dictionary
What Does Asterisk * Mean in Python
Encrypt & Decrypt Using Pycrypto Aes 256
How to Use Python Requests to Fake a Browser Visit A.K.A and Generate User Agent
How to One Hot Encode in Python
How to Efficiently Compare Two Unordered Lists (Not Sets)
Getting a Hidden Password Input
Python Dictionary: Are Keys() and Values() Always the Same Order