مساعدتي ترجمة قيمة طويلة، وأعرب في عرافة، مرة أخرى إلى وقت / زمن

StackOverflow https://stackoverflow.com/questions/610603

سؤال

ولدي قيمة التاريخ، والتي قيل لي هو 8 بايت، و "طويلة" (الملقب int64) قيمة واحدة، وتحويلها إلى عرافة:

60f347d15798c901

وكيف يمكن تحويل هذه القيم ومثل هذا، وذلك باستخدام PHP، في الوقت / التاريخ؟

وتحويله إلى عشري يعطيني: 243 71 209 96 87 152 201 1

وهناك القليل مزيد من المعلومات: القيمة الأصلية هي C # التاريخ والوقت، ويجب أن تمثل الوقت / التاريخ منذ حوالي 2 أو 3 أسابيع

.
هل كانت مفيدة؟

المحلول

و(شكرا إلى آخر thomasrutter، والذي أعطاني filetime عصر ويندوز):

ووتاريخ معين يبدو أن 64 بت ملف Endian طفيف التاريخ الوقت ويندوز، 60 F3 47 D1 57 98 C9 01، وهو ما يعادل quadword 01c99857d147f360 التي كعدد غير 128801567297500000

وهذا هو "عدد من فترات 100 نانو ثانية التي انقضت منذ 12:00 منتصف الليل، 1 يناير، 1601 ميلادي (C.E.) التوقيت العالمي (UTC) "

وبعد التحويل، وأنه يعطي الخميس، 26 فبراير 2009 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 الأرقام عرافة، ثم بعد ذلك اثنين، الخ).

و، وفقا ل هذا مصدر و

<اقتباس فقرة>   

وهناك علامة واحدة تمثل مائة نانو ثانية أو أحد عشر مليون من الثانية. وتمثل قيمة هذه الخاصية عدد فترات 100 نانو ثانية التي انقضت منذ 12:00:00 منتصف الليل، 1 يناير 0001، وهو ما يمثل.

وماذا يمكن أن الرحلة لكم هو أن للأسف PHP لا يمكن التعامل مع الأعداد الصحيحة 64 بت. ومن maxes بها في 32 بت. سوف يطفو مساعدة، ولكن ذلك لا يمنع hexdec () نفسه من التعامل فقط مع [إينتس]. لذلك قد يكون معقدا للقيام بذلك الرياضيات. قد لا تزال بحاجة إلى تقسيمه إلى قسمين، ثم الجمع بينهما في تعويم قبل الصب قيمة أكثر أهمية لتعويم وضرب من قبل 2 ^ 32 يلقي أيضا باسم تعويم. فمن الممكن أن PHP بنيت لأجهزة 64 بت قد لا يكون هذا القيد، ولكن أنا لا أعرف على وجه اليقين.

وأعتقد أنك يمكن تحويله إلى عشري مع hexdec(). وسيكون ذلك timestap أن تتمكن من العمل على مع date().

والقيمة التي أعطيت هي 36 الأرقام عرافة، أي 18 بايت قيمتها. هذا هو لا وInt64 تحويلها إلى عرافة.

والعودة الى كل من قدم لك شرح شكل ونطلب منهم ان اقول لكم الحقيقة هذه المرة:)

وتحرير: حسنا، الخطوة التالية: معرفة ما هو المقصود هذا العدد في الواقع يعني. القراد منذ عام 1970؟ بالمللي منذ 1 AD؟ هل تعرف ما هو المقصود سلسلة المثال الخاص بك لتمثيل؟

وإذا كان هذا هو نفس النوع من 64 بت عرافة NTP الطابع الزمني كما هو موضح هنا ، ثم يجب أن يكون تقسيم سلسلة عرافة على قدم المساواة في اثنين، وهذا هو، تخيل فاصل بين أول 8 أرقام ست عشرية وغيرهم من 8.

وتحويل النصف الأول (قيمة الأولى 32 بت ") إلى عدد صحيح مع hexdec ()، وهذا صحيح أن قيمة التاريخ في شكل الطابع الزمني يونكس (الثواني منذ 1 يناير 1970 بتوقيت جرينتش) والتي يمكنك بعد ذلك استخدام في تاريخ () وظيفة، الخ.

والجزء الثاني هو المقاطع كسور، ومفيدة إذا كنت بحاجة إلى دقة أدق من ثانية واحدة (وإن لم يكن العديد من التطبيقات القيام به، وفي PHP بنيت في التاريخ والوقت وظائف لا باستثناء microtime ()). هل أيضا تحويل هذا إلى عشري مع hexdec ().

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top