문제

나는 날짜 가치는,나는 말은 8 바이트를,하나의"길"(일명 int64)값을 변환하는 육:

60f347d15798c901

을 전환시키는 방법이 다음과 같은 문법을 이용하여 값을 사용하여,PHP,으로 시간/날짜?

로 변환하수 저:96 243 71 209 87 152 201 1

조금 더 많은 정보:원래 값은 C#DateTime 과를 나타내는 시간/날짜 약 2~3 주 전에.

도움이 되었습니까?

해결책

(Thomasrutter의 게시물 덕분에 Windows Filetime epoch를 준 Thomasrutter의 게시물 덕분) :

주어진 날짜는 Windows 64 비트 Little-Endian 파일 날짜 시간, 60 F3 47 D1 57 98 C9 01로 보이며, 이는 정수로서 128801567297500000 인 쿼드 워드 01C99857D147F360과 같습니다.

이것은 "1601 년 1 월 1 일 자정 (CE) 조정 범용 시간 (UTC) 이후 100 나노 초 간격의 수입니다.

전환 후 2009 년 2 월 26 일 21:18:49 UTC를 제공합니다.

샘플 코드 :

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

다른 팁

내가 발견 다른 참조 할 수 있는 좀 더 관련 정보입니다.이 경우에,윈도로 날짜와 시간에 사용되는 레지스트리에 있습니다.분명 이들은 또한 저장된 64 비트 값이 있습니다.

이 보고는 조금 더 도움으로 언급하는 로 끝나는 C?01 은 지표의 이 유형의 날짜.참고로 이것은 작은 endian(즉,가장 중요한 바이트에서 오른쪽)그래서 바이트는 잘못된 바이트 주문에 대한 hexdec()없이 반전이 그들 2 진수 자리 시간(즉,시작과 함께 가장 오른쪽 2 진수 숫자,그 다음에 두 개의,etc.).

과에 따르면, 이원,

단일 틱 중 하나를 나타냅백 나노초 또는 천만 분의 두 번째입니다.의 값 이 숙박 시설의 수를 나타냅 100-nanosecond 간격으로 경과된 이후 12:00:00midnight,January1,0001 나타냅니다.

무엇이 당신을 여행하는 것은 불행하게도 PHP 처리할 수 없는 64 비트의 정수입니다.그것은능하고 반면에서 32 비트입니다.레 도움이 될 것입니다,그러나 그는 멈추지 않는 hexdec()에서 자체만으로 대처 정.그래서 수 있습니다 복잡한을 이렇게 수학;당신이해야 할 수 있습니다 그것을 분할 두 가지로,그 다음 그들을 결합으로 부유물에 의해 주 더 중요한 가치를 부유물에 곱하여 2^32 또한 캐스팅으로 뜨. 가능성 PHP 구축을 위한 64-bit 하드웨어 없이,제한지 확실히 알 수 있습니다.

나는 당신이 그것을 10 진수로 변환 할 수 있다고 생각합니다. hexdec(). 그것은 당신이 함께 일할 수있는 타임 스테이프가 될 것입니다. date().

주어진 가치는 36 진수, 즉 18 바이트-가치입니다. 그게 ~ 아니다 an Int64 16 진로 변환.

당신에게 형식에 대한 설명을 한 사람으로 돌아가서 이번에는 진실을 말해달라고 요청하십시오 :)

편집 : 좋아요, 다음 단계 : 그 숫자가 실제로 무엇을 의미하는지 알아보십시오. 1970 년 이후 진드기? AD 1 이후 Millis? 당신의 예제 문자열이 무엇을 나타내야하는지 알고 있습니까?

동일한 유형의 경우 64 비트 16 진수 NTP 타임 스탬프 여기에 설명 된대로, 당신은 16 진수를 두 개로 똑같이 나누어야합니다.

전반전 (처음 32 비트 '가치)을 hexdec ()가있는 정수로 변환하면이 정수는 UNIX 타임 스탬프 형식 (1970 년 1 월 1 일 이후 초)의 날짜 값이됩니다. , 등.

두 번째 부분은 분수 섹션이며, 1 초보다 미세한 정확도가 필요한 경우 유용합니다 (많은 응용 프로그램은 그렇지 않지만 PHP의 내장 날짜 및 시간 함수는 마이크로 타임 ()을 제외하고는 그렇지 않음). 또한 이것을 hexdec ()로 10 진수로 변환합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top