John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

I want to take a 64-bit integer that I read and format it as a time/date for the person to read. I used the Google search on thepen here to see if anyone has written about FILETIME or GetFileTime, but nothing turned up.

Is this exposed in a known module somewhere, or does anyone have code to share?

—John

Replies are listed 'Best First'.
Re: Win32 FILETIME and 64-bit numbers
by jsprat (Curate) on Aug 05, 2002 at 19:34 UTC
      I used the getTime function from that post, and it doesn't work. I stripped it down to something simpler, and I find that I'm getting different output on each run for the same input! Any clue what's wrong here?
      sub getTime{ my ($filetimepointer) = @_; my $systemtime = pack("SSSSSSSS",0,0,0,0,0,0,0,0); my $FileToSystem = new Win32::API ("kernel32", "FileTimeToSystemTi +me", ['P','P'] , 'I'); $FileToSystem->Call($filetimepointer,$systemtime); my($year,$month,$wday,$day,$hour,$minute,$second,$msecond) = unpack("SSSSSSSS",$systemtime); return ($year,$month,$wday,$day,$hour,$minute,$second,$msecond); } sub printtime { my $time= shift; my ($year,$month,$wday,$day,$hour,$minute,$second,$msecond)= getTime +(time); $second += $msecond/1000; print "$year-$month-$day $hour:$minute:$second\n"; }
      my sample data is (in hex) f0 25 f6 89 15 13 c2 01. I read that from a file, and note that the same 8 bytes are in my unpacked $time variable that I pass into printtime as I see in the file.
        my ($year,$month,$wday,$day,$hour,$minute,$second,$msecond)= getTime (time);

        The parameter to getTime should be $time not time (don't you hate typos - I do). This would explain why you get a different "$time" every "time"...

        Update: BTW, when I run the code with the 64 bit number you are using, I get 6413 2002 as the year.

        my $ft = pack "LL", 0x89f625f0,0x01c21315; printtime $ft;

        gives me 2002-6-13 20:4:34.964.

Re: Win32 FILETIME and 64-bit numbers
by jmcnamara (Monsignor) on Aug 05, 2002 at 21:18 UTC
      I see: starting with a decimal representation, he just removed some characters from the right to bring it into the range of regular Perl-supported arithmetic (something like 53 or 56 bit significance, if I recall).

        Yes, anything more accurate would require Math::BigInt (or similar). That's what OLE::Storage_Lite uses to deal with this problem portably.

        --
        John.

Re: Win32 FILETIME and 64-bit numbers
by thunders (Priest) on Aug 06, 2002 at 13:16 UTC
    My module Win32::Filetime takes a file path as an argument, and creates a windows file handle. With that file handle it's simple to perform the necessary calculations. I let the windows API do all the work. from the windows API Documentation file time is defined like so:
    typedef struct _FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME, *PFILETIME;
    A little confusing as the bits need to be packed in the reverse order of the filetime integer. I plan to add a class method to directly decode the 64 bit-integer to that module, only problem is that i only encounter VT_FILETIME as a pointer to a struct through the API. Where else does this (bizzarre) time format crop up in the wild? I'd like to test it the raw integer but I've not yet seen a function that returns it in this form.
      Yes, I took out the part I really needed. I have the 64-bit ints stored in a file, not the actual timestamp of the file.

      I think VT_FILETIME is a COM/OLE name. I'm used to FILETIME in the Win32 API. It's used for timestamps and also for file sizes and offsets. In some functions the WINDOWS.H file passes the low and high halves as two 32-bit values, presumably so it would be compatible with compilers that didn't support __int64. For return values, I know one where the function return value is the low 32 bits, and the high 32 bits is in an out parameter!

      Naturally, I get rid of all that nonesence. I import the Win32 DLL's functions with int64 arguments (and structure members) when they are indeed that. In one case they have the halves backwards (sigh) so I have a wrapper to put it back together again.

      —John