帮助我翻译长时间的价值,以十六进制表示,回到日期/时间 [英] Help me translate long value, expressed in hex, back in to a date/time
问题描述
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屋!