Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pytz: _utcoffset has a wrong value for Iran

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

like image 310
saeedgnu Avatar asked Aug 15 '13 14:08

saeedgnu


People also ask

Does pytz account for daylight savings?

Timedelta and DSTpytz will help you to tell if an date is under DST influence by checking dst() method.

What does pytz timezone do?

Introduction. pytz brings the Olson tz database into Python. This library allows accurate and cross platform timezone calculations using Python 2.4 or higher. It also solves the issue of ambiguous times at the end of daylight saving time, which you can read more about in the Python Library Reference ( datetime.

What is the function to offset the date for daylight saving in Python?

You should use datetime. datetime. utcnow(). astimezone(tz) -- This gets the time in UTC and then offsets it from UTC according to whatever rules apply in the timezone tz.

How do I change timezone in Python?

Use the datetime. astimezone() method to convert the datetime from one timezone to another. This method uses an instance of the datetime object and returns a new datetime of a given timezone.


1 Answers

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.

like image 113
mata Avatar answered Sep 21 '22 08:09

mata