Python 2.5.1 broken os.stat module

Joe Salmeri JoeSalmeri at hotmail.com
Sun Jun 3 16:23:55 CEST 2007


""Martin v. Löwis"" <martin at v.loewis.de> wrote in message 
news:4662750b$0$29898$9b622d9e at news.freenet.de...
>> The short explaination of this issue is that the timestamp shown when
>> you do a dir on a file that is on an NTFS volume changes by an hour
>> when DST starts and also when DST ends, even though the file has NOT
>> been modified!!!  Note that this only happens if you have the setting
>> turned on to automatically adjust for DST (this is the default in
>> Windows).
>
> You are misinterpreting what you are seeing. Windows is not claiming
> that the modification time changes when DST starts. Instead, it is
> claiming that the *same* time now has a *different* textual
> representation, because the computer now has moved to a different
> time zone.
>
> When you explicitly change the time zone of your computer, you will
> notice that all file time stamps immediately change also.

It appears that you may have missed part of my tests.  Sorry it was such a 
long reply but I was trying to provide a lot of detail so that others had a 
clear understanding of what was going on.

I understand that the actual UTC time value for the file has *not* changed.

That local textual representation of the modification timestamp is what 
people and programs look at and work with and is what is displayed by the 
dir command and what Explorer displays.

Changing the timezone will defintely change the "textual representation" of 
all timestamps just as you say (even though the actual UTC value has *not* 
changed), however, when DST starts/ends the "textual representation" of the 
timestamps on some files WILL ALSO CHANGE when the automatically adjust for 
DST setting is turned on.

That is *not* my opinion or interpretation, it is clearly documented by 
Microsoft and is also documented in the long article that I provided the 
link for in my reply yesterday.  It was also demonstrated in the second test 
I provided yesterday and is also demonstrated in the article I provided the 
link to.

In the following comments I am referring to the textual representation of 
the timestamp that the user is working with (I understand that the interal 
UTC timestamp for the file has *not* changed).

The issue occurs when the timestamp for the file is in a period when DST was 
not in effect and DST is in effect for the current time OR when the 
timestamp for the file is in a period when DST was in effect and DST is not 
in effect for the current time.

While it is true that I did change the timezone in the first part of the 
test (to establish the baseline), in the second part of the tests where the 
difference you are referring to occured, the timezone was *not* changed, the 
only thng that occured was that DST started.

In that test the file had a timestamp of 01/01/2007 07:00 PM as shown by the 
dir command results.

When the date progressed to a point after DST had started Windows now 
reports the timestamp on that *unmodified* file now is 01/01/2007 08:00 PM.

I did not change the timezone, the only thing that occurred was DST started.

The internal UTC timestamp did NOT change, the issue is in Windows textual 
representation of that UTC timestamp to my local timezone and DST values, 
Windows now reports that the modification timestamp on the file as 1 hour 
later (again the actual UTC timestamp did *not* change).

To the end user the file "appears" to have been modified an hour later than 
it was the day before even though it was not changed.

Over the years this issue has caused all sorts of problems for backup 
programs and CVS (greatly detailed in the article I provided the link for).

>> Even though Python 2.5.1 is correct this presents a NEW problem
>> because it differs from what XP SP 2 (wrongly) reports.  I am sure
>> this will cause a lot of confusion for people as it already appears
>> that others have stumbled on this difference.
>
> However, please understand that the problem is *not* caused by the
> results returned from os.stat. Instead, the difference comes from
> your choice of calling localtime() to break down the timestamp
> to day, hour, and minute. If you write a different function
> windows_localtime, that behaves the same way that the Windows
> rendering behaves, you will get the same results.
>
>> To the end user it appears the file was modifed when in fact it was
>> not.
>
> That's because the user is misinterpreting the data that Windows
> reports. Windows isn't saying the file changed, Windows says that
> the timezone changed.

You mixed up my tests, in that case as shown above the timezone did *not* 
change, the only thing that changed was that DST started and the file was 
created during a time when DST was not in effect.

>> Having this difference between Python and Windows makes it difficult
>> to write code that depends on those values being in sync.
>
> No. Just write a windows_localtime function, and be done.

For those that are interested here is a function that you can use in place 
of time.localtime that will return values that match what Windows 
(incorrectly) reports.

There may be a better way to do this but so far I this code seems to work.

I ran a test against the Python\lib directory using the check_dates.py 
program previously posted with it modified to use the localtime_windows 
function in place of the time.localtime function calls and all create and 
write timestamps returned now match what Windows (incorrectly) reports.

import datetime
import time

def localtime_windows(seconds):
    value   = time.localtime(seconds)
    now     = time.localtime()

    # Compare DST in value versus DST now

    if value[8] == 0 and now[8] == 1:
        # When original date is NOT in DST but now date is in DST add 1 hour
        new_value   = datetime.datetime(value.tm_year, value.tm_mon, 
value.tm_mday, value.tm_hour, value.tm_min, value.tm_sec)  + 
datetime.timedelta(hours=1)
        value       = new_value.timetuple()
    elif value[8] == 1 and now[8] == 0:
        # When original date is in DST and now date is NOT in DST subtract 1 
hour
        new_value   = datetime.datetime(value.tm_year, value.tm_mon, 
value.tm_mday, value.tm_hour, value.tm_min, value.tm_sec)  + 
datetime.timedelta(hours=-1)
        value       = new_value.timetuple()

    return value


































More information about the Python-list mailing list