3

I've determined that I need to convert a Windows FILETIME type to something PHP can work with. I want this to be a PHP function.

Say I have this value: 60 F3 47 D1 57 98 C9 01

Step 1: (Thanks to this page http://www.cyanwerks.com/file-format-url.html) I know I need to change the order to 01 C9 98 57 D1 47 F3 60

Step 2: ?????

lynn
  • 2,868
  • 5
  • 31
  • 34

3 Answers3

4

From the MSDN documentation:

Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
1

Courtesy of Hugh Bothwell in answer to this question: Help me translate long value, expressed in hex, back in to a date/time

<?php

    // strip non-hex characters
    function hexstring($str) {
        $hex = array(
                '0'=>'0',       '1'=>'1',       '2'=>'2',       '3'=>'3',       '4'=>'4',
                '5'=>'5',       '6'=>'6',       '7'=>'7',       '8'=>'8',       '9'=>'9',
                'a'=>'a',       'b'=>'b',       'c'=>'c',       'd'=>'d',       'e'=>'e',       'f'=>'f',
                'A'=>'a',       'B'=>'b',       'C'=>'c',       'D'=>'d',       'E'=>'e',       'F'=>'f'
        );

        $t = '';
        $len = strlen($str);
        for ($i=0; $i<$len; ++$i) {
                $ch = $str[$i];
                if (isset($hex[$ch]))
                        $t .= $hex[$ch];
        }

        return $t;
    }

    // swap little-endian to big-endian
    function flip_endian($str) {
        // make sure #digits is even
        if ( strlen($str) & 1 )
                $str = '0' . $str;

        $t = '';
        for ($i = strlen($str)-2; $i >= 0; $i-=2)
                $t .= substr($str, $i, 2);

        return $t;
    }

    // convert hex string to BC-int
    function hex_to_bcint($str) {
        $hex = array(
                '0'=>'0',       '1'=>'1',       '2'=>'2',       '3'=>'3',       '4'=>'4',
                '5'=>'5',       '6'=>'6',       '7'=>'7',       '8'=>'8',       '9'=>'9',
                'a'=>'10',      'b'=>'11',      'c'=>'12',      'd'=>'13',      'e'=>'14',      'f'=>'15',
                'A'=>'10',      'B'=>'11',      'C'=>'12',      'D'=>'13',      'E'=>'14',      'F'=>'15'
        );

        $bci = '0';
        $len = strlen($str);
        for ($i=0; $i<$len; ++$i) {
                $bci = bcmul($bci, '16');

                $ch = $str[$i];
                if (isset($hex[$ch]))
                        $bci = bcadd($bci, $hex[$ch]);
        }

        return $bci;
    }

    // WARNING! range clipping
    //   Windows date time has range from 29000 BC to 29000 AD
    //   Unix time only has range from 1901 AD to 2038 AD
    // WARNING! loss of accuracy
    //   Windows date time has accuracy to 0.0000001s
    //   Unix time only has accuracy to 1.0s
    function win64_to_unix($bci) {
        // Unix epoch as a Windows file date-time value
        $magicnum = '116444735995904000';

        $t = bcsub($bci, $magicnum);    // Cast to Unix epoch
        $t = bcdiv($t, '10000000', 0);  // Convert from ticks to seconds

        return $t;
    }

// get input
$dtval = isset($_GET["dt"]) ? strval($_GET["dt"]) : "0";
$dtval = hexstring($dtval);             // strip non-hex chars

// convert to quadword
$dtval = substr($dtval, 0, 16);         // clip overlength string
$dtval = str_pad($dtval, 16, '0');  // pad underlength string
$quad = flip_endian($dtval);

// convert to int
$win64_datetime = hex_to_bcint($quad);

// convert to Unix timestamp value
$unix_datetime = win64_to_unix($win64_datetime);

?><html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Windows datetime test code</title>
</head>

    <form method="get">
        <label>Datetime value: <input name="dt" type="text" value="<?php echo $dtval; ?>"/></label>
        <input type="submit" />
    </form>
    <hr />
    Result:
        Quad: <?php echo $quad; ?><br />
        Int: <?php echo $win64_datetime; ?><br />
        Unix timestamp: <?php echo $unix_datetime; ?><br />
        Date: <?php echo date("D, d F Y H:i:s e", $unix_datetime); ?><br />
<body>
</body>
</html>
Community
  • 1
  • 1
lynn
  • 2,868
  • 5
  • 31
  • 34
  • 2
    You couldn't have written all that code in the three minutes since posting the question, so unless you knew the answer before you asked, that's not your code. Could you please cite the source? – Rob Kennedy Mar 04 '09 at 18:30
  • Iit was the solution from http://stackoverflow.com/questions/610603/help-me-translate-long-value-expressed-in-hex-back-in-to-a-date-time And I can't delete this question as redundant. Editing response to give credit where it's due. – lynn Mar 04 '09 at 18:41
  • 2
    That is an very ugly bit of code for dealing with a such simple problem. – Cheeso Mar 05 '09 at 05:25
1

What kind of time does PHP need? Is it a time_t? if so, just subtract your DateTime from the unix epoch (1970-jan-01 UTC) and grab the TotalSeconds value.

Cheeso
  • 189,189
  • 101
  • 473
  • 713