From 8a10eb2cc6b57017229aafef01c44fdfce9e5411 Mon Sep 17 00:00:00 2001 From: Kevin B Kenny Date: Sat, 30 Oct 2004 21:36:46 +0000 Subject: Fixed conversion between FILETIME and Tcl time -Bug 926106 --- ChangeLog | 4 +++ win/tclWinFile.c | 76 +++++++++++++++++++++----------------------------------- 2 files changed, 33 insertions(+), 47 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2d5ae2a..8546152 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,10 @@ * generic/clock.c: Replaced WIN32 macro with __WIN32__. [Bug 1054357]. Thanks to David Gravereaux for the patch. + * win/tclWinFile.c: Removed a long-standing bug that causes + incorrect conversion between file time and UTC time if + the file time is recorded in a different Daylight Saving Time + status than the current one. [Bug 926106] 2004-10-29 Don Porter diff --git a/win/tclWinFile.c b/win/tclWinFile.c index 8406a3e..cb6ab53 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -11,7 +11,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinFile.c,v 1.67 2004/10/07 14:50:24 vincentdarley Exp $ + * RCS: @(#) $Id: tclWinFile.c,v 1.68 2004/10/30 21:36:48 kennykb Exp $ */ //#define _WIN32_WINNT 0x0500 @@ -24,6 +24,14 @@ #include /* For TclpGetUserHome(). */ /* + * The number of 100-ns intervals between the Windows system epoch + * (1601-01-01 on the proleptic Gregorian calendar) and the + * Posix epoch (1970-01-01). + */ + +#define POSIX_EPOCH_AS_FILETIME 116444736000000000 + +/* * Declarations for 'link' related information. This information * should come with VC++ 6.0, but is not in some older SDKs. * In any case it is not well documented. @@ -1976,58 +1984,32 @@ NativeStatMode(DWORD attr, int checkLinks, int isExec) return (unsigned short)mode; } +/* + *------------------------------------------------------------------------ + * + * ToCTime -- + * + * Converts a Windows FILETIME to a time_t in UTC. + * + * Results: + * Returns the count of seconds from the Posix epoch. + * + *------------------------------------------------------------------------ + */ + static time_t -ToCTime( - FILETIME fileTime) /* UTC Time to convert to local time_t. */ +ToCTime( FILETIME fileTime ) /* UTC Time to convert to local time_t. */ { - FILETIME localFileTime; - SYSTEMTIME systemTime; - struct tm tm; - if (FileTimeToLocalFileTime(&fileTime, &localFileTime) == 0) { - return 0; - } - if (FileTimeToSystemTime(&localFileTime, &systemTime) == 0) { - return 0; - } - tm.tm_sec = systemTime.wSecond; - tm.tm_min = systemTime.wMinute; - tm.tm_hour = systemTime.wHour; - tm.tm_mday = systemTime.wDay; - tm.tm_mon = systemTime.wMonth - 1; - tm.tm_year = systemTime.wYear - 1900; - tm.tm_wday = 0; - tm.tm_yday = 0; - tm.tm_isdst = -1; - - return mktime(&tm); + LARGE_INTEGER convertedTime; + convertedTime.LowPart = fileTime.dwLowDateTime; + convertedTime.HighPart = (LONG) fileTime.dwHighDateTime; + return (time_t) ( (convertedTime.QuadPart + - (Tcl_WideInt) POSIX_EPOCH_AS_FILETIME) + / (Tcl_WideInt) 10000000); } #if 0 - - /* - * Borland's stat doesn't take into account localtime. - */ - - if ((result == 0) && (buf->st_mtime != 0)) { - TIME_ZONE_INFORMATION tz; - int time, bias; - - time = GetTimeZoneInformation(&tz); - bias = tz.Bias; - if (time == TIME_ZONE_ID_DAYLIGHT) { - bias += tz.DaylightBias; - } - bias *= 60; - buf->st_atime -= bias; - buf->st_ctime -= bias; - buf->st_mtime -= bias; - } - -#endif - - -#if 0 /* *------------------------------------------------------------------------- * -- cgit v0.12