This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: new timezones
Type: behavior Stage: test needed
Components: Extension Modules Versions: Python 3.2, Python 3.3, Python 2.7
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: Arfrever, Rioky, amaury.forgeotdarc, belopolsky, lemburg
Priority: normal Keywords:

Created on 2011-11-23 20:00 by Rioky, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (10)
msg148204 - (view) Author: Aleksey (Rioky) Date: 2011-11-23 20:00
Hi Guys,
Since 31 august 2011 in Russian Federation always DST time.
http://worldtimezone.net/dst_news/dst_news_russia36.html

But
>>> time.tzname
('MSK', 'MSK')
>>> time.localtime().tm_isdst
0
>>> time.timezone
-10800
>>> time.altzone
-14400

i think tm_isdst must be always 1 for my zone, or timezone must be equal altzone
msg148207 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2011-11-23 21:35
On my Ubuntu machine, I get:

$ zdump -v Europe/Moscow | grep 201[0-9]
Europe/Moscow  Sat Mar 27 22:59:59 2010 UTC = Sun Mar 28 01:59:59 2010 MSK isdst=0 gmtoff=10800
Europe/Moscow  Sat Mar 27 23:00:00 2010 UTC = Sun Mar 28 03:00:00 2010 MSD isdst=1 gmtoff=14400
Europe/Moscow  Sat Oct 30 22:59:59 2010 UTC = Sun Oct 31 02:59:59 2010 MSD isdst=1 gmtoff=14400
Europe/Moscow  Sat Oct 30 23:00:00 2010 UTC = Sun Oct 31 02:00:00 2010 MSK isdst=0 gmtoff=10800
Europe/Moscow  Sat Mar 26 22:59:59 2011 UTC = Sun Mar 27 01:59:59 2011 MSK isdst=0 gmtoff=10800
Europe/Moscow  Sat Mar 26 23:00:00 2011 UTC = Sun Mar 27 03:00:00 2011 MSK isdst=0 gmtoff=14400
[and nothing else, whereas other locations can show changes up to year 2499]

If I read this information correctly, this says that about 8 months ago, DST was not applied as usual; instead, the definition of MSK changed from UTC+3 to UTC+4.
Of course Python uses the same data, so is right to display tm_idst=0.

OTOH, time.timezone should be -4*3600==-14400, and here I think Python is wrong.  Also, time.daylight should be zero, whereas:

$ TZ=Europe/Moscow ./python
Python 3.3.0a0 (default:53cc2668d54f, Nov 23 2011, 22:19:40) 
[GCC 4.4.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> time.tzname, time.timezone, time.daylight
(('MSK', 'MSK'), -10800, 1)

The error comes from the way Python computes timezone and daylight: it queries the tm_gmtoff of two timestamps, one close to the first of January, the other close to the first of July.  But last January the previous definition of the timezone was still in force...  and indeed, when I changed the code to use *next* January instead, I have the expected values.

Is there an algorithm that gives the correct answer?  Taking the 1st of January closest to the current date would not work either.  Or is there another way (in portable C) to approach timezones?
msg148208 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2011-11-23 22:12
Amaury Forgeot d'Arc wrote:
> 
> The error comes from the way Python computes timezone and daylight: it queries the tm_gmtoff of two timestamps, one close to the first of January, the other close to the first of July.  But last January the previous definition of the timezone was still in force...  and indeed, when I changed the code to use *next* January instead, I have the expected values.
> 
> Is there an algorithm that gives the correct answer?  Taking the 1st of January closest to the current date would not work either.  Or is there another way (in portable C) to approach timezones?

A fairly "correct" way is to query the time zone database at time module
import time by using the DST and GMT offset of that time.

IMO time.timezone and time.daylight should be deprecated since they
will give wrong results around DST changes (both switch times and
legal changes such as the described one) in long running processes
such as daemons.
msg148212 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2011-11-23 23:17
> A fairly "correct" way is to query the time zone database at time module
> import time by using the DST and GMT offset of that time.

But that does not give the *other* timezone :-(

> IMO time.timezone and time.daylight should be deprecated since they
> will give wrong results around DST changes (both switch times and
> legal changes such as the described one) in long running processes
> such as daemons.

time.timezone is the non-DST timezone: this value does not change around
the DST change date.  That's why the current implementation uses "absolute"
dates like the of January: DST changes are often in March and October.

What about this algorithm:
- pick the first of January and the first of July surrounding the current date
- if both have tm_idst==0, the region has no DST. Use the current GMT offset for
  both timezone and altzone; daylight=0
- otherwise, use the *current* time and get its DST and GMT offset. This is enough
to compute both timezone and altzone (with the relation altzone=timezone-3600)
msg148213 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2011-11-23 23:19
Another way to fix the issue is to wait 40 days.  There won't be any release in-between anyway!
msg148233 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2011-11-24 09:18
Amaury Forgeot d'Arc wrote:
> 
> Amaury Forgeot d'Arc <amauryfa@gmail.com> added the comment:
> 
>> A fairly "correct" way is to query the time zone database at time module
>> import time by using the DST and GMT offset of that time.
> 
> But that does not give the *other* timezone :-(

Which other timezone ?

You set time.timezone to the GMT offset of the import time
and then subtract another 3600 seconds in case tm_isdst is
set.

>> IMO time.timezone and time.daylight should be deprecated since they
>> will give wrong results around DST changes (both switch times and
>> legal changes such as the described one) in long running processes
>> such as daemons.
> 
> time.timezone is the non-DST timezone: this value does not change around
> the DST change date. 

No, but time.daylight changes and time.timezone can change in situations
like these where a region decides to change the way DST is dealt
with, e.g. switches to the DST timezone or moves the switchover date.

Since both values are tied to a specific time I don't think it's
a good idea to have them as module globals.

> That's why the current implementation uses "absolute"
> dates like the of January: DST changes are often in March and October.

Such an algorithm can be used as fallback solution in case
tm_isdst is -1 (unknown), but not in case the DST information
is available.

> What about this algorithm:
> - pick the first of January and the first of July surrounding the current date
> - if both have tm_idst==0, the region has no DST. Use the current GMT offset for
>   both timezone and altzone; daylight=0

Those two steps are not necessary. If tm_isdst == 0, you already know that
the current time zone is not DST.

> - otherwise, use the *current* time and get its DST and GMT offset. This is enough
> to compute both timezone and altzone (with the relation altzone=timezone-3600)

That's what I suggested above.
msg148238 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2011-11-24 10:31
> > But that does not give the *other* timezone :-(
> Which other timezone ?
I meant the other timezone *name*.

I think we don't understand each other:
- time.timezone is the offset of the local (non-DST) timezone.
- time.altzone is the offset of local DST timezone.
They don't depend on the current date, they depend only on the timezone database.
localtime() only gives the timezone for a given point in time, and the time module needs to present two timezones.
msg148240 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2011-11-24 10:49
Amaury Forgeot d'Arc wrote:
> 
> Amaury Forgeot d'Arc <amauryfa@gmail.com> added the comment:
> 
>>> But that does not give the *other* timezone :-(
>> Which other timezone ?
> I meant the other timezone *name*.
> 
> I think we don't understand each other:
> - time.timezone is the offset of the local (non-DST) timezone.
> - time.altzone is the offset of local DST timezone.

Yes, I know.

> They don't depend on the current date, they depend only on the timezone database.
> localtime() only gives the timezone for a given point in time, and the time module needs to present two timezones.

Right, but they should only depend on the data in the timezone
database at the time of import of the module and not determine
the values by looking at specific dates in the past.

The only problem is finding out whether the locale uses DST in
case the current import time points to a non-DST time. This can
be checked by looking at Jan 1st and June 1st after
the current import time (ie. in the future) and then testing
tm_isdst. If there is a DST change, then you set
time.altzone = time.timezone - 3600. Otherwise, you set
time.altzone = time.timezone.
msg249283 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2015-08-28 17:33
Since Russia has fixed this bug legislatively last year, can we close the issue now?

http://www.theguardian.com/world/2014/jul/01/russia-state-duma-daylight-saving-time-summer
msg252163 - (view) Author: Alexander Belopolsky (belopolsky) * (Python committer) Date: 2015-10-02 21:27
Since nobody responded, I am closing this issue.
History
Date User Action Args
2022-04-11 14:57:24adminsetgithub: 57675
2015-10-02 21:27:07belopolskysetstatus: open -> closed
resolution: out of date
messages: + msg252163
2015-08-28 17:33:21belopolskysetmessages: + msg249283
2011-11-26 23:46:46Arfreversetnosy: + Arfrever
2011-11-24 10:49:01lemburgsetmessages: + msg148240
2011-11-24 10:31:27amaury.forgeotdarcsetmessages: + msg148238
2011-11-24 09:18:16lemburgsetmessages: + msg148233
2011-11-23 23:19:27amaury.forgeotdarcsetmessages: + msg148213
2011-11-23 23:17:35amaury.forgeotdarcsetmessages: + msg148212
2011-11-23 22:12:48lemburgsetmessages: + msg148208
2011-11-23 21:35:33amaury.forgeotdarcsetnosy: + amaury.forgeotdarc
messages: + msg148207
2011-11-23 20:57:11ezio.melottisetnosy: + lemburg, belopolsky
stage: test needed

components: + Extension Modules
versions: + Python 3.2, Python 3.3
2011-11-23 20:00:47Riokycreate