I have run into a situation where QFileInfo::lastModified is off by 1 hour. I attach a program that reproduces this problem, and it reproduces on a Windows 8.1 system in Russia/Moscow timezone, with Visual Studio 2013 as compiler and Qt 5.4.1. The affected timestamp is 1413957600, which is Oct 22 2014 6:00 UTC. The timezone in Russia was UTC+4 at that date. It switched to UTC+3 on Oct 26. Note that +4 was not actually DST, we switched from 'permanent +4' to 'permanent +3' due to specific decision of the government, it was not an automatic change.
There's what I see in debugger:
- I start with 1413957600, which is 6:00 UTC on Oct 22.
- When qfilesystemengine_win.cpp:fileTimeToQDateTime converts the timestamp from the file system, around line 1481, it ends up with local time of 10:00. This is correct, the TZ offset was +4 on Oct 22 2014.
- Eventually, qdatetime.cpp:qt_mktime is called, and calls mktime. The input is 10:00, tm_isdst is -1, the output is 1413961200, exactly 3600 more than original timestamp.
The documentation for mktime is not exactly clear, but it say that "The C run-time library assumes the United States’s rules for implementing the calculation of Daylight Saving Time", so it presumably looks at the current time zone offset (+3), decides that DST on Sep 16 2015 and Oct 22 2014 must be the same, and therefore substracts 3 hours from local time, after Windows has added 4, resulting in 1 hour difference.
I am not entirely sure how to fix it, but SystemTimeToTzSpecificLocalTime seems more competent than mktime, and if it's used in some places, it is better to use it everywhere? Or, when creating QDateTime from FILETIME, we can use Qt::OffsetFromUTC spec, so that future conversions are more robust?