I think maybe this is what you want...

Use Math::BigInt;

########################################################################
########
# Convert Microsoft's FILETIME variant into standard Epoch time
########################################################################
########

sub ConvertToEpoch {
    my $ts = shift;

    if( $ts->HighPart == 0 and $ts->LowPart == 0 ) {
        return 0;
    }
    
    my $hi = Math::BigInt->from_hex( sprintf("0x%x", $ts->HighPart) );
    my $lo = Math::BigInt->from_hex( sprintf("0x%x", $ts->LowPart) );

    
    $hi->blsft(32);                 # shift high order bits left by 32
    
    my $lastlogon = Math::BigInt->new('0');
    $lastlogon->badd($hi);
    $lastlogon->badd($lo);
    
# $lastlogon now contains the number of 100 nanosecond intervals since
01/01/1601

    $lastlogon->bdiv('10000000');           # convert to seconds
    $lastlogon->bsub('11644473600');        # number of seconds between
01/01/1601 and 01/01/1970
    
    return $lastlogon->numify;
}


The reference to the scalar you are getting is in fact an object that
represents a 64 bit integer. The object has methods HighPart and LowPart
which return the high 32 bits and low 32 bits respectively. I use
Math::BigInt to build a BigInt from these two values, then convert to
seconds, then translate from 01/01/1601 to 01/01/1970.

Since the function could be passed 0, and a 32 bit value can't handle
-369 years worth of seconds, I "short circuit" by returning a 0 if a 0
date of zero is passed. 

-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Deans,
Glenn (IT Solutions US)
Sent: Wednesday, February 04, 2009 1:34 PM
To: [email protected]
Subject: RE: Date math with UTC Coded Time

Thanks Bill.  I was able to do something like that with the long integer
for pwdLastSet, but I'm having trouble getting a usable value.  I can't
seem to figure out what data I'm getting or, I guess, how to access it
properly.  If I don't use Win32::OLE::Variant, and mod the code like
below, I get what looks like a reference to a scalar, but the
dereferenced variable doesn't have anything that I would call useful.
OLE & references are definitely my weak point, but I just don't know how
to get anything that I could feed to Date::Time, Date::Calc, Time::Local
or one of the other date modules.

        until ($recset->EOF){
                $modified = $recset->Fields('modifyTimeStamp')->Value;
                print "Modified=$modified ($$modified)\n";
                # displays
Modified=Win32::OLE::Variant=SCALAR(0x19c4fbc) (25317948)
                $recset->MoveNext;
        }

Am I just trying to access the returned value improperly?

Glenn

-----Original Message-----
From: Bill Luebkert [mailto:[email protected]] 
Sent: Tuesday, February 03, 2009 7:54 PM
To: Deans, Glenn (IT Solutions US)
Cc: [email protected]
Subject: Re: Date math with UTC Coded Time

Deans, Glenn (IT Solutions US) wrote:
> Can anyone give me some direction for handling the UTC Coded time?  I
> think I'm just missing something obvious, but I just can't get this
into
> a useable format for doing any kind of date math.

I know nothing of ADO, but given an epoch time or a UTC time, it
shouldn't
be that hard to convert.  You'll need to find out why you're getting the
strange value for $modified back before you can fix it though.

>       until ($recset->EOF){
>               $modified = $recset->Fields('modifyTimeStamp')->Value;
>               print "Modified=$modified\n";
>               # displays 
>               $recset->MoveNext;
>       }
> 
> It seems any dates from last year come out as 1/9/2009 2:22:05 AM.
I'm
> not sure what I'm doing wrong, but maybe someone could point it out to
> me?  Then once that is corrected, how can you easily tell if it's > 90
> days since it doesn't seem to be an epoch time?

Once you have your times in epoch format, it's just simple math to check
for 90 days (90 * 86400 seconds) difference.

Are you literally getting '1/9/2009 2:22:05 AM' back for $modified ?

If so, I have no idea why.  I would expect a string like
'20090203164851Z'
which you can easily parse into pieces and feed to Time::Local::timegm
to
get epoch time.

If not, what are you literally getting ?
_______________________________________________
ActivePerl mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
_______________________________________________
ActivePerl mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to