www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - d_time2FILETIME

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
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).

Andrei
Apr 10 2009
next sibling parent "Denis Koroskin" <2korden gmail.com> writes:
On Fri, 10 Apr 2009 18:07:20 +0400, Andrei Alexandrescu
<SeeWebsiteForEmail 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).

 Andrei

You may take a look at Boost Posix Time System: http://www.boost.org/doc/libs/1_38_0/doc/html/date_time/posix_time.html It has a plenty of functions that convert time to and from various formats, including Posix time and Windows FILETIME.
Apr 10 2009
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 10 Apr 2009 10:07:20 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail 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
Apr 10 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 On Fri, 10 Apr 2009 10:07:20 -0400, Andrei Alexandrescu 
 <SeeWebsiteForEmail 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
Apr 10 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Andrei Alexandrescu wrote:
         ulong t = (dt - ticksFrom1601To1970) * (10_000_000 / 
 TicksPerSecond);

That must be addition, otherwise I go back in time to 1200 or so. Now everything works, thanks to all who answered. The upside of all this is that now setFileTimes works on both Windows and Posix. :o) Andrei
Apr 10 2009