Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

converting microsoft timestamps

by glwtta (Hermit)
on Jun 18, 2004 at 17:09 UTC ( [id://368002]=perlquestion: print w/replies, xml ) Need Help??

glwtta has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

Do any perl date modules handle Microsoft timestamps properly? The format for them is, I believe, the number of 100 nanosecond chunks since midnight Jan 1 1601.

I don't know enough about time handling (including various leap units) to trust my own conversion.

What's the proper way to handle one of these?

Thanks

Replies are listed 'Best First'.
Re: converting microsoft timestamps
by BrowserUk (Patriarch) on Jun 18, 2004 at 18:11 UTC

    Assuming from your description that you are talking about FILETIME structs, you could do it like this.

    #! perl -slw use strict; use Win32API::File qw[ FdGetOsFHandle ]; use Win32::API::Prototype; ApiLink( 'kernel32', 'BOOL FileTimeToSystemTime( LPFILETIME lpFileTime, LPSYSTEMTIME lpSystemTime )' ) or die $^E; ApiLink( 'kernel32', 'BOOL GetFileTime( HANDLE hFile, LPFILETIME lpCreationTime, LPFILETIME lpLastAccessTime, LPFILETIME lpLastWriteTime )' ) or die $^E; ## Get an OSfilehandle for the curent script my $osfh = FdGetOsFHandle( fileno( DATA ) ) or die $!; ## 3 x quadword buffers for the FILETIME structs my( $ctime, $atime, $wtime ) = ( chr(0) x 8 ) x 3; ## Get them GetFileTime( $osfh, $ctime, $atime, $wtime ) or die $^E; ## 8 word buffer for the SYSTEMTIME struct my $systime = chr( 0 ) x 16; for( $ctime, $atime, $wtime ) { ##Convert the FILETIMEs to SYTEMTIMEs FileTimeToSystemTime( $_, $systime ) or die $^E; printf "Year: %4d Month: %2d DOW: %1d Day: %2d Hour: %2d Minutes: +%2d Seconds: %2d Milliseconds: %3d\n", unpack 'v8', $systime; } __DATA__ P:\test>368002 Year: 2004 Month: 6 DOW: 5 Day: 18 Hour: 17 Minutes: 47 Seconds: 5 M +illiseconds: 283 Year: 2004 Month: 6 DOW: 5 Day: 18 Hour: 18 Minutes: 7 Seconds: 38 M +illiseconds: 689 Year: 2004 Month: 6 DOW: 5 Day: 18 Hour: 18 Minutes: 7 Seconds: 37 M +illiseconds: 1

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
      That seems reasonable, except I am on UNIX, Win32 APIs really don't help much. Any pure perl solutions?

      Thanks

        In that case you want something like this

        #! perl -slw use strict; use Win32API::File qw[ FdGetOsFHandle ]; use Win32::API::Prototype; ApiLink( 'kernel32', 'BOOL GetFileTime( HANDLE hFile, LPFILETIME lpCreationTime, LPFILETIME lpLastAccessTime, LPFILETIME lpLastWriteTime )' ) or die $^E; my $osfh = FdGetOsFHandle( fileno( DATA ) ) or die $!; my( $ctime, $atime, $wtime ) = ( chr(0) x 8 ) x 3; GetFileTime( $osfh, $ctime, $atime, $wtime ) or die $^E; ## Ignore the stuf above, ## it's just a way of getting some FILETIMEs for testing. sub msFiletimeToUnix{ my ( $lo, $hi ) = unpack 'V2', $_[ 0 ]; my $nanosecs = $hi * 2**32 + $lo; return int( ($nanosecs - 116444736010000000) / 1E7 ); } for( $ctime, $atime, $wtime ) { print scalar localtime( msFiletimeToUnix( $_ ) ); } __DATA__ P:\test>368002 Fri Jun 18 18:47:04 2004 Fri Jun 18 20:10:35 2004 Fri Jun 18 20:10:33 2004

        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        "Memory, processor, disk in that order on the hardware side. Algorithm, algoritm, algorithm on the code side." - tachyon
Re: converting microsoft timestamps
by waswas-fng (Curate) on Jun 18, 2004 at 17:48 UTC
    When you say "Microsoft timestamps" what are you referring to? they use many different formats in different applications and API's for example MS SQL Server uses one whereas IE cookies use another. Please be more specific.


    -Waswas
      It's the one I described - apparently it's a FILETIME struct (as BrowserUk points out), the specific place I am getting them is ActiveDirectory fields for various account control functions.
Re: converting microsoft timestamps
by jmcnamara (Monsignor) on Jun 18, 2004 at 23:09 UTC

    Here is a method to decode the timestamp from a previous node:
    #!/usr/bin/perl -wl use strict; use Date::Calc 'Add_Delta_DHMS'; my $vt_filetime = '126697423010137600'; # Disregard the 100 nanosecond units (but you could save them for +later) $vt_filetime = substr($vt_filetime, 0, 11); my $days = int( $vt_filetime / (24*60*60) ); my $hours = int( ($vt_filetime % (24*60*60)) / (60*60) ); my $mins = int( ($vt_filetime % (60*60)) / 60 ); my $secs = $vt_filetime % 60 ; my @date = Add_Delta_DHMS(1601, 1, 1, 0, 0, 0, $days, $hours, $min +s, $secs); # Format @date as you wish print "@date"; __END__ Prints: 2002 6 28 12 51 41

    --
    John.

Re: converting microsoft timestamps
by rir (Vicar) on Jun 18, 2004 at 18:34 UTC
    This is simpler than you believe, leap units are not an issue. Just find the Microsoft timestamp value for the origin of whatever timestamp type you want. Substract this constant from the value and multiply by the correct factor for the conversion. Think centigrade to/from Fahrenheit.

    You might have to unpack and repack the values.

    Be well.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://368002]
Approved by sacked
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (2)
As of 2024-04-25 23:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found