[Interest] Relashionship between time_t and QDateTime

Constantin Makshin cmakshin at gmail.com
Tue Aug 27 20:59:44 CEST 2013


(re-sending to the list, sorry for the mistake)

One key is in the "Remarks" section of
SystemTimeToTzSpecificLocalTime()'s documentation
(http://msdn.microsoft.com/en-us/library/windows/desktop/ms724949(v=vs.85).aspx):
> The SystemTimeToTzSpecificLocalTime function may calculate the local time incorrectly under the following conditions:
> - *The time zone uses a different UTC offset for the old and new years*.
> - The UTC time to be converted and the calculated local time are in different years.

Another key is in the description of the DYNAMIC_TIME_ZONE_INFORMATION
structure
(http://msdn.microsoft.com/en-us/library/windows/desktop/ms724253(v=vs.85).aspx):
> Dynamic daylight saving time provides support for time zones whose boundaries for daylight saving time change from year to year. ... After the time zone has been updated, *the current time zone setting is applied to all time operations, even when the time in question occurred before the time zone changed*.

Windows can store information about daylight saving transitions for past
years, but always uses one for the current year. And since daylight
saving transition dates and time tend to slightly drift from year to
year, there's absolutely no guarantees of getting correct time
conversion results; in general case 1-hour error is nearly inevitable.
If you're on Windows, either calculate and apply DST yourself or forget
about correct "UTC <-> local time" conversions.

On 08/27/2013 10:27 PM, Daniel Bowen wrote:
> From http://msdn.microsoft.com/en-us/library/windows/desktop/ms724290(v=vs.85).aspx
> 
> The MSDN library states:
> 
> "
> To account for daylight saving time when converting a file time to a local time, use the following sequence of functions instead of using FileTimeToLocalFileTime:
> FileTimeToSystemTime
> SystemTimeToTzSpecificLocalTime
> SystemTimeToFileTime
> "
> 
> For example:
> 	(incoming fileTimeUtc)
> 	FILETIME fileTimeLocal;
> 	SYSTEMTIME systemTimeUtc = {0}, systemTimeLocal = {0};
> 	::FileTimeToSystemTime(&fileTimeUtc, &systemTimeUtc);
> 	::SystemTimeToTzSpecificLocalTime(NULL, &systemTimeUtc, &systemTimeLocal);
> 	::SystemTimeToFileTime(&systemTimeLocal, &fileTimeLocal);
> 	// SYSTEMTIME will lose accuracy less than a millisecond.  We'll tack that back on.
> 	fileTimeLocal += (fileTimeUtc % Millisecond);
> 
> If this is on Windows and before Vista, then past timezones might not be correct if the rules are different than the current set of daylight savings transition rules (only Vista and later has the dynamic timezone stuff that tracks timezone transition changes in years past).  In the QDateTime docs I see "On Windows and Windows CE, where the system doesn't support historical DST data, historical accuracy is not maintained with respect to DST."  I don't believe that's quite true - Windows support historical DST data if you use the calls above, and its on Vista or later.  You can also use calls like GetDynamicTimeZoneInformation and GetTimeZoneInformationForYear on Vista and later for more explicit historical timezone info.
> 
> 
> The thing to remember is that time_t and FILETIME and QDateTime (at least <=5.1) all represent a moment in time without regard for timezone.  Like 2013-08-27T11:50:00. It's up to you to track which timezone the time_t or FILETIME you have belongs to.  (i.e., 2013-08-27T11:50:00-06:00)
> 
> I think the best way to track things if timezones are in the mix is to track the date/time as one thing, and separately track the timezone offset for that date/time.  Then you can convert reliably between different local times or UTC.  We ended up with our own class for tracking time that does that.  (Kind of like the .NET DateTimeOffset compared to the DateTime class).
> 
> 
> -Daniel
> 
> -----Original Message-----
> From: interest-bounces+qtmailinglist1=bowensite.com at qt-project.org [mailto:interest-bounces+qtmailinglist1=bowensite.com at qt-project.org] On Behalf Of Constantin Makshin
> Sent: Tuesday, August 27, 2013 11:40 AM
> To: Qt Interest
> Subject: Re: [Interest] Relashionship between time_t and QDateTime
> 
> When converting time from UTC to local time, Windows uses the *current* state of daylight saving, not one that was active at the time the original timestamp is "pointing" to.
> 
> On 08/27/2013 01:55 PM, Frank Hemer wrote:
>> On Tuesday 27 August 2013 10:19:06 Calogero Mauceri wrote:
>>> On 8/26/2013 7:30 PM, Thiago Macieira wrote:
>>>> On segunda-feira, 26 de agosto de 2013 17:42:58, Calogero Mauceri wrote:
>>>>> QDateTime myDateTime = QDateTime::fromTime_t(f_mtime);
>>>>>
>>>>> The date time printed doing a myDateTime.toString() is
>>>>>
>>>>>       Wed Dec 5 12:36:18 2007
>>>>>
>>>>> Retrieving the last modified information using QFileInfo, the 
>>>>> result is different
>>>>>
>>>>>       QFileInfo fi(filepath);
>>>>>       QDateTime myDateTime = fi.lastModified();
>>>>>
>>>>> I get this result
>>>>>
>>>>>       Wed Dec 5 11:36:18 2007
>>>>>
>>>>> That is there is one hour difference. I guess the difference is due 
>>>>> to the daylight saving management, but I can not understand how 
>>>>> that management is performed.
>>>>>
>>>>> Note: if I look at the file properties on Windows dialog, the last 
>>>>> modified time is shown as
>>>>>
>>>>>       Wed Dec 5 12:36:18 2007
>>>>
>>>> Ah, Windows...
>>>>
>>>> The problem might be simply a matter of timezones. The timestamps on 
>>>> files on Windows are not stored with time_t, but with some 
>>>> Windows-specific data. We get a FILETIME back from Win32.
>>>>
>>>> Anyway, up until Qt 5.2, you cannot trust the output of a QDateTime 
>>>> with qDebug since it does not include the timezone. You have to 
>>>> ensure that the
>>>>
>>>> dates you're comparing by text are in the same timezone:
>>>> 	qDebug() << dt.toUTC();
>>>
>>> Thanks for your reply.
>>>
>>> Unfortunately the problem is still there even if I force a toUTC() 
>>> conversion for both QDateTime, either the one initialized from time_t 
>>> or the one returned by QFileInfo :/.
>>> Similarly
>>>
>>> 	QDateTime dtFromTime_t = QDateTime::fromTime_t(mtime).toUTC();
>>> 	QDateTime dtFromFileInfo = fi.lastModified().toUTC();
>>> 	int sec = ABS(dtFromTime.secsTo(dtFromFileInfo));	// sec returned is 3600
>>
>> Daylight savings handling in windows is somehow 'weird'.
>> The timestamps of files change when switching the system time from 
>> summer time to winter time and vice versa.
>>
>> Frank



-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20130827/2f5e519a/attachment.sig>


More information about the Interest mailing list