0

I have the following code

import datetime
import pytz

tz_offset = datetime.datetime.now(pytz.timezone('Africa/Khartoum' or 'GMT')).strftime('%z')
print(tz_offset)

The expected output is "+0200" but it gives "+0300".

Since pytz gets its info from IANA, I contacted them and they said it is correctly set in their database. Here is their email reply:

On 6/19/20 10:40 AM, Ubay Abdelgadir wrote:

Khartoum's time zone is +2 since 1/Nov/2017. I think it is wrong in the IANA database:

Zone Africa/Khartoum 2:10:08 - LMT 1931
    2:00 Sudan CA%sT 2000 Jan 15 12:00
    3:00 - EAT 2017 Nov  1
    2:00 - CAT

That data entry says that Africa/Khartoum has been +02 since 2017 Nov 1, so it appears to agree .with your statement that Khartoum's time zone is +2 since 1/Nov/2017.

Edit

I solved this by updating pytz version, it was 2016.7 which is outdated for my case (change happened in 2017)

Obay Abd-Algader
  • 1,079
  • 12
  • 25

1 Answers1

1

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
FObersteiner
  • 22,500
  • 8
  • 42
  • 72
  • I tried this in my laptop, didn't work. But tried it on an online testing website https://repl.it and it worked! – Obay Abd-Algader Jun 22 '20 at 03:41
  • Strangely, the above pytz code didn't work on my laptop (all offsets where +0300), but worked in an online testing website. – Obay Abd-Algader Jun 22 '20 at 04:56
  • @ObayAbd-Algader: that is strange... for reference: I'm using Python 3.8.2 x64 on Windows 10 with pytz 2020.1. – FObersteiner Jun 22 '20 at 05:52
  • Yes. I just found that my pytz version was 2016.7 which is outdated for my case. After I updated the module it your code worked fine. – Obay Abd-Algader Jun 22 '20 at 07:26
  • @ObayAbd-Algader: very good. I'd suggest not to use `pytz` anyway unless you need compatibility with older scripts or Python2. For now, `dateutil` is in my eyes the better option (e.g. has no "`localize` trap"). In the future, Python 3.9 will have the [`zoneinfo`](https://docs.python.org/3.9/library/zoneinfo.html) module, so timezone functionality will be build-in (no 3rd party packages needed anymore). – FObersteiner Jun 22 '20 at 07:36
  • Good news about the zoneinfo module. If I hand control over which library is used I would switch to dateutil, the problem occurred to me while using Odoo. – Obay Abd-Algader Jun 22 '20 at 07:48