10

Correct value:

>>> pytz.timezone('Asia/Tehran').utcoffset(datetime(2013, 1, 1)).total_seconds()/3600.0
3.5

>>> pytz.timezone('Asia/Tehran').utcoffset(datetime(2013, 1, 1)).total_seconds()
12600.0

Incorrect value:

>>> pytz.timezone('Asia/Tehran')._utcoffset.total_seconds()/3600.0
3.433333333333333

>>> pytz.timezone('Asia/Tehran')._utcoffset.total_seconds()
12360.0

I wonder if that _utcoffset attribute is used in utcoffset() method, why the method is working while the attribute is wrong.
Looks like a bug anyway.
Nothing changes if you replace Asia/Tehran with Iran

>>> print pytz.VERSION
2012c

OS: Linux Mint 15 (Olivia)
Using Python 2.7

saeedgnu
  • 4,110
  • 2
  • 31
  • 48

1 Answers1

19

Let's see what's going on here:

>>> tz = pytz.timezone('Asia/Tehran')
>>> tz
<DstTzInfo 'Asia/Tehran' LMT+3:26:00 STD>

This means the timezone is expressed in LMT - which is solar time. That's why you see an utcoffset of 12360 - no error here, it's just calculated using a different reference.

Now if you do:

>>> d = tz.localize(datetime(2013, 1, 1))
>>> d
datetime.datetime(2013, 1, 1, 0, 0, tzinfo=<DstTzInfo 'Asia/Tehran' IRST+3:30:00 STD>)
>>> d.utcoffset()
datetime.timedelta(0, 12600)

The localize method caused the representation to switch to the correct time zone used at that date and place, which is IRST with an utcoffset of 12600 seconds.

And that's just what the utcoffset method of the tzinfo object does - it localizes the given datetime object and returns it's utcoffset.

Likewise if you currently do:

>>> d = datetime.now(tz)
>>> d
datetime.datetime(2013, 8, 15, 20, 46, 4, 705896, tzinfo=<DstTzInfo 'Asia/Tehran' IRDT+4:30:00 DST>)
>>> d.utcoffset()
datetime.timedelta(0, 16200)

You'll get the datetime expressed in IRDT because currently daylight saving time is in effect in that timezone.

mata
  • 67,110
  • 10
  • 163
  • 162
  • 1
    Why does pytz default to LMT? It seems very unlikely that someone would expect or want to see LMT offset by default. Pytz should either adopt a sensible default and with a warning that the offset depends on the specific date, or just throw an error. – rinspy Apr 23 '19 at 08:58
  • @rinspy The behaviour is historic, see https://bugs.launchpad.net/pytz/+bug/1319939/comments/12 for some information. Also, the `_utcoffset` attribute isn't public api. – mata Apr 25 '19 at 20:24