avoid TzSpecificLocalTimeToSystemTime
svn: r840
This commit is contained in:
parent
6e6e54d411
commit
7c147ecaec
|
@ -2035,24 +2035,72 @@ char *scheme_expand_string_filename(Scheme_Object *o, const char *errorin, int *
|
||||||
# define GET_FF_NAME(fd) fd.cFileName
|
# define GET_FF_NAME(fd) fd.cFileName
|
||||||
static time_t convert_date(const FILETIME *ft)
|
static time_t convert_date(const FILETIME *ft)
|
||||||
{
|
{
|
||||||
LONGLONG l;
|
LONGLONG l, delta;
|
||||||
FILETIME ft2;
|
FILETIME ft2;
|
||||||
SYSTEMTIME st, st2;
|
SYSTEMTIME st;
|
||||||
|
TIME_ZONE_INFORMATION tz;
|
||||||
|
|
||||||
/* FindFirstFile incorrectly shifts for daylight saving. Counteract
|
/* FindFirstFile incorrectly shifts for daylight saving. It
|
||||||
the difference by using FileTimeToLocalFileTime, which also
|
subtracts an hour to get to UTC when daylight saving is in effect
|
||||||
shifts incorrectly. There's a race condition here, because we
|
now, even when daylight saving was not in effect when the file
|
||||||
might cross the daylight-saving boundary between the time that
|
was saved. Counteract the difference. There's a race condition
|
||||||
FindFirstFile runs and FileTimeToLocalFileTime runs. Cross your
|
here, because we might cross the daylight-saving boundary between
|
||||||
fingers... */
|
the time that FindFirstFile runs and GetTimeZoneInformation
|
||||||
|
runs. Cross your fingers... */
|
||||||
FileTimeToLocalFileTime(ft, &ft2);
|
FileTimeToLocalFileTime(ft, &ft2);
|
||||||
FileTimeToSystemTime(&ft2, &st);
|
FileTimeToSystemTime(&ft2, &st);
|
||||||
TzSpecificLocalTimeToSystemTime(NULL, &st, &st2);
|
|
||||||
SystemTimeToFileTime(&st2, &ft2);
|
delta = 0;
|
||||||
|
if (GetTimeZoneInformation(&tz) == TIME_ZONE_ID_DAYLIGHT) {
|
||||||
|
/* Daylight saving is in effect now, so there may be a bad
|
||||||
|
shift. Check the file's date. */
|
||||||
|
int start_day_of_month, end_day_of_month, first_day_of_week, diff, end_shift;
|
||||||
|
|
||||||
l = ((((LONGLONG)ft2.dwHighDateTime << 32) | ft2.dwLowDateTime)
|
/* Valid only when the months match: */
|
||||||
|
first_day_of_week = (st.wDayOfWeek - (st.wDay - 1 - (((st.wDay - 1) / 7) * 7)));
|
||||||
|
if (first_day_of_week < 0)
|
||||||
|
first_day_of_week += 7;
|
||||||
|
|
||||||
|
diff = (tz.DaylightDate.wDayOfWeek - first_day_of_week);
|
||||||
|
if (diff < 0)
|
||||||
|
diff += 7;
|
||||||
|
start_day_of_month = 1 + (((tz.DaylightDate.wDay - 1) * 7)
|
||||||
|
+ diff);
|
||||||
|
|
||||||
|
diff = (tz.StandardDate.wDayOfWeek - first_day_of_week);
|
||||||
|
if (diff < 0)
|
||||||
|
diff += 7;
|
||||||
|
end_day_of_month = 1 + (((tz.StandardDate.wDay - 1) * 7)
|
||||||
|
+ diff);
|
||||||
|
|
||||||
|
/* Count ambigious range (when the clock goes back) as
|
||||||
|
in standard time. We assume that subtracting the
|
||||||
|
ambiguous range does not go back into the previous day,
|
||||||
|
and that the shift is a multiple of an hour. */
|
||||||
|
end_shift = ((tz.StandardBias - tz.DaylightBias) / 60);
|
||||||
|
|
||||||
|
if ((st.wMonth < tz.DaylightDate.wMonth)
|
||||||
|
|| ((st.wMonth == tz.DaylightDate.wMonth)
|
||||||
|
&& ((st.wDay < start_day_of_month)
|
||||||
|
|| ((st.wDay == start_day_of_month)
|
||||||
|
&& (st.wHour < tz.DaylightDate.wHour))))) {
|
||||||
|
/* Daylight saving had not yet started. */
|
||||||
|
delta = ((tz.StandardBias - tz.DaylightBias) * 60);
|
||||||
|
} else if ((st.wMonth > tz.StandardDate.wMonth)
|
||||||
|
|| ((st.wMonth == tz.StandardDate.wMonth)
|
||||||
|
&& ((st.wDay > end_day_of_month)
|
||||||
|
|| ((st.wDay == end_day_of_month)
|
||||||
|
&& (st.wHour >= (tz.StandardDate.wHour
|
||||||
|
- end_shift)))))) {
|
||||||
|
/* Daylight saving was already over. */
|
||||||
|
delta = ((tz.StandardBias - tz.DaylightBias) * 60);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
l = ((((LONGLONG)ft->dwHighDateTime << 32) | ft->dwLowDateTime)
|
||||||
- (((LONGLONG)0x019DB1DE << 32) | 0xD53E8000));
|
- (((LONGLONG)0x019DB1DE << 32) | 0xD53E8000));
|
||||||
l /= 10000000;
|
l /= 10000000;
|
||||||
|
l += delta;
|
||||||
|
|
||||||
return (time_t)l;
|
return (time_t)l;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user