Python 2.5.1 broken os.stat module
Joe Salmeri
JoeSalmeri at hotmail.com
Sun Jun 3 10:23:55 EDT 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