14.11.04 02:55:01, Martin Stjernholm wrote:
So I gather that older windowsen store local time in the timestamps, as opposed to NT, and that FileTimeToLocalFileTime is a nop on the old OS's.
No. The FILETIME values in the WIN32_FIND_DATA structure are defined as the number of 100-nanosecond intervals since January 1, 1601 00:00 UTC on *all* Windows versions. Likewise, the behaviour of FileTimeToLocalFileTime, and the bug, is identical on NT and W9x.
It all depends on the underlying *file system*.
On NTFS volumes, the time is stored as UTC, so it's easy to calculate the difference to January 1, 1601 00:00 UTC directly.
On FAT volumes, the time is stored as local time, as a heritage from MS-DOS days. This means that this local time must be converted to UTC first before calculating the FILETIME. During this conversion, all Windows versions exhibit the same bug, using the *current* DST status instead of the DST status at that time. So the FILETIME value can be off by one hour for FAT volumes.
Now the CRT _stat implementation uses FileTimeToLocalFileTime to convert this value back to local time - which suffers from the same DST bug. Then the undocumented function __loctotime_t is used to convert this local time to a time_t, and this function correctly accounts for DST at that time.
On FAT volumes, the conversion error while retrieving the FILETIME, and the conversion error of FileTimeToLocalFileTime exactly cancel each other out, so the final result of the _stat implementation is always correct.
On NTFS volumes however, there is no conversion error while retrieving the FILETIME because the file system already stores it as UTC, so the conversion error of FileTimeToLocalFileTime can cause the final result to be 1 hour off.
The current Pike implementation does it exactly the other way round - the result is always correct on NTFS volumes, but can be 1 hour off on FAT volumes.
The simple calculation I proposed has exactly the same properties as the current Pike implementation - the result is always correct on NTFS volumes, but can be 1 hour off on FAT volumes. What's more, it's considerably less bloated and does not completely break Pike on W9x.
If you want to always get correct results for NTFS *and* FAT volumes, you'd have to detect which kind of file system the file is in, and then use my proposed calculation for NTFS and the standard _stat implementation for FAT. However this would be quite a hassle just because of an occasional 1 hour off on FAT volumes.
Summing up, I renew my pledge to replace the current Pike implementation with my proposed calculation.
Cheers, Axel