Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the windows FILETIME structure include leap seconds?

Tags:

The FILETIME structure counts from January 1 1601 (presumably the start of that day) according to the Microsoft documentation, but does this include leap seconds?

like image 901
Lawrence D'Anna Avatar asked Sep 24 '08 23:09

Lawrence D'Anna


People also ask

What is Windows Filetime?

A Windows file time is a 64-bit value that represents the number of 100-nanosecond intervals that have elapsed since 12:00 midnight, January 1, 1601 A.D. (C.E.) Coordinated Universal Time (UTC). Windows uses a file time to record when an application creates, accesses, or writes to a file.

Does NTP include leap seconds?

Unlike the POSIX conventions , the NTP clock is frozen and does not advanced during the leap second, so there is no need to set it back one second at the end of the leap second.


1 Answers

The question shouldn't be if FILETIME includes leap seconds.

It should be:

Do the people, functions, and libraries, who interpret a FILETIME (i.e. FileTimeToSystemTime) include leap seconds when counting the duration?

The simple answer is "no". FileTimeToSystemTime returns seconds as 0..59.


The simpler answer is: "of course not, how could it?".

My Windows 2000 machine doesn't know that there were 2 leap seconds added in the decade since it was released. Any interpretation it makes of a FILETIME is wrong.


Finally, rather than relying on logic, we can determine by direct experimental observation, the answer to the posters question:

var
    systemTime: TSystemTime;
    fileTime: TFileTime;
begin
    //Construct a system-time for the 12/31/2008 11:59:59 pm
    ZeroMemory(@systemTime, SizeOf(systemTime));
    systemtime.wYear := 2008;
    systemTime.wMonth := 12;
    systemTime.wDay := 31;
    systemTime.wHour := 23;
    systemtime.wMinute := 59;
    systemtime.wSecond := 59;

    //Convert it to a file time
    SystemTimeToFileTime(systemTime, {var}fileTime);

    //There was a leap second 12/31/2008 11:59:60 pm
    //Add one second to our filetime to reach the leap second
    filetime.dwLowDateTime := fileTime.dwLowDateTime+10000000; //10,000,000 * 100ns = 1s

    //Convert the filetime, sitting on a leap second, to a displayable system time
    FileTimeToSystemTime(fileTime, {var}systemTime);

    //And now print the system time
    ShowMessage(DateTimeToStr(SystemTimeToDateTime(systemTime)));

Adding one second to

12/31/2008 11:59:59pm

gives

1/1/2009 12:00:00am

rather than

1/1/2009 11:59:60pm

Q.E.D.

Original poster might not like it, but god intentionally rigged it so that a year is not evenly divisible by a day. He did it just to screw up programmers.

like image 173
Ian Boyd Avatar answered Oct 11 '22 02:10

Ian Boyd