d_time2FILETIME

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Fri Apr 10 09:17:24 PDT 2009


Steven Schveighoffer wrote:
> On Fri, 10 Apr 2009 10:07:20 -0400, Andrei Alexandrescu 
> <SeeWebsiteForEmail at erdani.org> wrote:
> 
>> Hello,
>>
>> I want to port the function setFileTimes available in Phobos/Posix to 
>> Windows. Does anyone know of a simple way to convert a d_time value to 
>> a FILETIME value? d_time is Ticks since 1-1-1970 and FILETIME contains 
>> quanta of 100-nanoseconds since 1-1-1601. So there's only some 
>> shifting and scaling involved, but the shifting constant is tricky :o).
> 
> What you need is the constant that is the number of Ticks (either 100ns 
> ticks or whatever) from 1601 to 1970.
> 
> I redid most of the tango time stuff, but those constants were already 
> there before my time (no pun intended).  The number of seconds between 
> 1/1/1601 and 1/1/1970 is 11644473600.  Scale that to whatever you wish.
> 
> Note that we do not take into account leap-seconds, not sure if that 
> matters to you.
> 
> -Steve

Thanks a lot! However, something's amiss a bit. I have this code:

     static d_time FILETIME2d_time(const FILETIME *ft)
     {
         SYSTEMTIME st = void;
         if (!FileTimeToSystemTime(ft, &st))
             return d_time_nan;
         return SYSTEMTIME2d_time(&st, 0);
     }

     FILETIME d_time2FILETIME(d_time dt)
     {
         enum ulong ticksFrom1601To1970 = 11_644_473_600UL * TicksPerSecond;
         static assert(10_000_000 % TicksPerSecond == 0);
         ulong t = (dt - ticksFrom1601To1970) * (10_000_000 / 
TicksPerSecond);
         FILETIME result = void;
         result.dwLowDateTime = cast(uint) (t & uint.max);
         result.dwHighDateTime = cast(uint) (t >> 32);
         return result;
     }

     unittest
     {
         auto dt = getUTCtime;
         auto ft = d_time2FILETIME(dt);
         auto dt1 = FILETIME2d_time(&ft);
         assert(dt == dt1, text(dt, " != ", dt1));
     }

which fails with 1239379868629 != 156195960030165. Let me clarify that a 
little:

1_239_379_868_629 != 156_195_960_030_165

So it looks like I made a mistake somewhere because the difference is 
very large. A FILETIME has 100-ns increments, and there are 10_000_000 
of those in a second. So I get the ticks from 1601 to dt, then I divide 
by TicksPerSecond to get the seconds, and finally I multiply by 10M to 
get the 100-ns count. Where am I wrong?


Thanks,

Andrei



More information about the Digitalmars-d mailing list