帮助我翻译长时间的价值,以十六进制表示,回到日期/时间 [英] Help me translate long value, expressed in hex, back in to a date/time

查看:131
本文介绍了帮助我翻译长时间的价值,以十六进制表示,回到日期/时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个日期值,我被告知是8个字节,一个单长(又称int64)值,并转换为十六进制:

  60f347d15798c901 

如何使用PHP转换此值和值,到时间/日期?



将其转换为十进制给出:
96 243 71 209 87 152 201 1



A一些更多的信息:原始值是一个C#DateTime,它应该代表大约2或3周前的时间/日期。

解决方案

(感谢thomasrutter的帖子,这给了我Windows文件时间):



给定的日期似乎是一个Windows 64位的小端文件日期时间,
60 f3 47 d1 57 98 c9 01,
,相当于四字
01c99857d147f360
作为整数为
128801567297500000



这是1月1日午夜以来已经过去的100纳秒间隔

1601 AD(CE)协调世界时(UTC)



转换后,它给
Thu,2009年2月26日21:18:49 UTC



示例代码:

 <?php 

//剥去非十六进制字符
函数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'=& ='d','e'=>'e','f'=>'f',
'A'=>'a','B'=>'b' ,'C'=>'c','D'=>'d','E'=>'e','F'=>'f'
);

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

return $ t;
}

//将big-endian交换到big-endian
函数flip_endian($ str){
//确保#digits甚至
if(strlen($ str)& 1)
$ str ='0'。 $ str;

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

return $ t;
}

//将十六进制字符串转换为BC-int
函数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'=& '=> '13','E'=> '14','F'=> '15'
);

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

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

return $ bci;
}

//警告!范围限制
// Windows日期时间的范围从29000 BC到29000 AD
// Unix时间的范围从1901年到2038年AD
//警告!精度损失
// Windows日期时间精确到0.0000001s
// Unix时间只有精度到1.0s
函数win64_to_unix($ bci){
// Unix时代作为Windows文件日期时间值
$ magicnum ='116444735995904000';

$ t = bcsub($ bci,$ magicnum); // Cast to Unix epoch
$ t = bcdiv(​​$ t,'10000000',0); //从ticks转换为秒

return $ t;
}

//获取输入
$ dtval = isset($ _ GET [dt])? strval($ _ GET [dt]):0;
$ dtval = hexstring($ dtval); // strip non-hex chars

//转换为四字
$ dtval = substr($ dtval,0,16); // clip overlength string
$ dtval = str_pad($ dtval,16,'0'); // pad underlength string
$ quad = flip_endian($ dtval);

//转换为int
$ win64_datetime = hex_to_bcint($ quad);

//转换为Unix时间戳值
$ unix_datetime = win64_to_unix($ win64_datetime);

?>< html>
< head>
< meta http-equiv =Content-Typecontent =text / html; charset = utf-8/>
< title> Windows日期时间测试代码< / title>
< / head>

< form method =get>
< label> Datetime值:< input name =dttype =textvalue =<?php echo $ dtval;?>/>< / label>
< input type =submit/>
< / form>
< hr />
结果:
Quad:<?php echo $ quad; >< br />
Int:<?php echo $ win64_datetime; >< br />
Unix时间戳:<?php echo $ unix_datetime; >< br />
日期:<?php echo date(D,d F Y H:i:s e,$ unix_datetime); >< br />
< body>
< / body>
< / html>


I have a date value, which I'm told is 8 bytes, a single "long" (aka int64) value, and converted to hex:

60f347d15798c901

How can I convert this and values like this, using PHP, into a time/date?

Converting it to decimal gives me: 96 243 71 209 87 152 201 1

A little more info: the original value is a C# DateTime, and should represent a time/date about 2 or 3 weeks ago.

解决方案

(Thanks to thomasrutter's post, which gave me the Windows filetime epoch):

The given date appears to be a Windows 64-bit little-endian file date-time, 60 f3 47 d1 57 98 c9 01, which is equivalent to the quadword 01c99857d147f360 which as an integer is 128801567297500000

This is "the number of 100-nanosecond intervals that have elapsed since 12:00 midnight, January 1, 1601 A.D. (C.E.) Coordinated Universal Time (UTC)"

After conversion, it gives Thu, 26 February 2009 21:18:49 UTC

Sample code:

<?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>

这篇关于帮助我翻译长时间的价值,以十六进制表示,回到日期/时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆