Bana uzun değeri çevirmek yardımcı, geri tarih / zaman için, onaltılık ifade

5 Cevap php

Ben söyledim ben bir tarih değeri, 8 bayt, tek bir "uzun" (aka Int64) değeri ve onaltılık dönüştürülür var:

60f347d15798c901

Nasıl bu ve bunun gibi değerler, PHP kullanarak, bir zaman / tarih çevirebilirim?

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

Biraz daha fazla bilgi: özgün değeri bir C # DateTime olduğunu ve yaklaşık 2 ya da 3 hafta önce bir zaman / tarih temsil etmelidir.

5 Cevap

(Bana, Windows FILETIME çığır verdi thomasrutter en yazılan, teşekkürler):

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

Örnek kod:

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

Biraz daha ilgili bilgilere işaret olabilir another reference hangi bulundu. Bu durumda, kayıt defterinde kullanılan Windows tarih ve saati. Görünüşe göre bu da 64 bit değerler olarak saklanır.

O C? 01 biten tarih bu tür bir göstergesi olduğunu bahseder gibi bu, biraz daha yardımcı arıyor. (Yani, en sağ 2 basamaklı hex ile başlar bu küçük endian (sağda, yani en önemli bayt) yani bayt bir anda onlara 2 altıgen basamak ters olmadan hexdec () için yanlış bayt sırası olduğunu unutmayın, sonra önümüzdeki iki, vb.)

Ve göre this source,

Tek bir kene yüz nanosaniye veya bir saniyenin on milyonda temsil eder. Bu özelliğin değeri temsil 12:00:00 gece yarısı, 1 Ocak 0001, beri geçen 100 nanosecond aralıkları sayısını temsil eder.

Seni ne olabilir ne yazık ki PHP 64 bitlik tamsayılar işleyemez olmasıdır. Bu 32 bit maxes. Şamandıralar yardımcı olacaktır, ama bu sadece ints ile başa çıkma itibaren) (kendisini hexdec durmuyor. Yani bu matematik yapmak için karmaşık olabilir; Eğer hala dalgalanmaya daha önemli bir değer döküm ve aynı zamanda float olarak döküm 2 ^ 32 ile çarpılarak bir şamandıra bunları birleştirmek, ikiye bölmek gerekebilir. It's possible that PHP built for 64-bit hardware may not have this limitation, but I don't know for sure.

Sana hexdec(). Yani date(). ile çalışabilir bir timestap olacak bir ondalık int dönüştürmek inanıyorum

Verdiğin değeri 36 basamaklı hex, yani 18 byte-değer. İşte not bir Int64 hex dönüştürülür bulunuyor.

Size geri formatının açıklamasını verdi kim gidin ve bu sefer gerçeği söylemek isteyin :)

EDIT: Tamam, bir sonraki adım: bu sayı aslında demek ne demek olduğunu öğrenmek. 1970 yılından beri Keneler? MS 1 yılından bu yana millis? Eğer örnek dize temsil etmek ne demek olduğunu biliyor musunuz?

O 64 bit hex NTP timestamp as described here, daha sonra iki eşit onaltılık dize bölme edilmelidir aynı tip ise, yani, ilk 8 onaltılık basamak ve diğer 8 arasında bir ayırıcı düşünün.

Hexdec ile bir tamsayı () içine ilk yarısını (ilk 32 bit değerinde) dönüştürmek ve bu tamsayı Unix timestamp formatında tarih değeri olacaktır (saniye beri 1 Ocak 1970 GMT) sonra date () fonksiyonu kullanabilirsiniz vs

İkinci bölüm kullanışlı, fraksiyonel bölümler Eğer (çok değil uygulama yapmak ve PHP'nin tarih ve zaman içinde inşa gerçi fonksiyonlar) (Microtime'da için hariç değil) bir saniyeden daha doğruluğu daha ince gerekiyorsa. Ayrıca hexdec () ile ondalık bu dönüştürmek istiyorsunuz.