За последние 24 часа нас посетили 50462 программиста и 1758 роботов. Сейчас ищут 899 программистов ...

int64 (FILETIME to unix TIMESTAMP)

Тема в разделе "Прочие вопросы по PHP", создана пользователем engager, 16 июн 2010.

  1. engager

    engager Активный пользователь

    С нами с:
    21 янв 2009
    Сообщения:
    1.106
    Симпатии:
    1
    Имеется б бинарник, запись которго содержит значение типа FILETIME. Выдержка из msdn:

    Код (Text):
    1. FILETIME Structure
    2.  
    3. Contains a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (UTC).
    4. Syntax
    5. Copy
    6. typedef struct _FILETIME {
    7.   DWORD dwLowDateTime;
    8.   DWORD dwHighDateTime;
    9. } FILETIME, *PFILETIME;
    64-битное значение, представляющие количество 100-наносекундных интервалов, прошедших с 01.01.1601

    Имеется необходимость перевести в unix_timestamp, который, как известно имеет 32битную природу. Все бы ничего, можно округлить до секунд значение FILETIME, но как это реализовать на пхп? Можно написать нечто:
    PHP:
    1. function FILETIMEtoUNIXtime($FILETIME) {
    2.   return round(($FILETIME - 116444736000000000) / 10000000);
    3. }
    4.  
    Но что передавать в параметре?
    Ну вычитали 8 байт из файла, сдвинули, проорили (OR), получили переполнение и остались с непонятной хренью в 32 бита.
    Есть мысли?

    переименую тему для поисковиков. ибо для пыхи я не смог нагуглить решения...
     
  2. engager

    engager Активный пользователь

    С нами с:
    21 янв 2009
    Сообщения:
    1.106
    Симпатии:
    1
    пока что видится только отдельно привести в таймштампу и к юникс-эпохе старшее слово и младшее, а потом просуммировать.
    вроде должно получиться.
    ща попробую.
     
  3. engager

    engager Активный пользователь

    С нами с:
    21 янв 2009
    Сообщения:
    1.106
    Симпатии:
    1
    сделал через float (там пришлось использовать логарифмы))
    пришлось, конечно поизвращаться...
    ничего, что я сам с собой тут беседую?))
     
  4. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    покаж, покаж-ка что получилось
     
  5. engager

    engager Активный пользователь

    С нами с:
    21 янв 2009
    Сообщения:
    1.106
    Симпатии:
    1
    Пусть тут будет, вдруг пригодится кому...
    Код конечно же не претендует на оптимальность, если кто причешет, буду рад. У самого пока времени нет))
    PHP:
    1.  
    2.  
    3.     function int2float($i) {
    4.     $x32 = 4294967296;
    5.     $i = (float)$i;
    6.     if ($i < 0) return $i + $x32 + 1; else return $i; /* signed int32 overflow костыль */
    7.   }
    8.  
    9.   function FILETIMEtoUNIXtime($FILETIME) {
    10. // FILETIME is a 64-bit unsigned integer representing
    11. // the number of 100-nanosecond intervals since January 1, 1601
    12. // UNIX timestamp is number of seconds since January 1, 1970
    13.  
    14.      $x32 = 4294967296;
    15.      $sec_btw_epoch = (float)(116444736 * 100);
    16.  
    17.      $low =
    18.           (ord($FILETIME[0])) |
    19.           (ord($FILETIME[1]) << 8)  |
    20.           (ord($FILETIME[2]) << 16) |
    21.           (ord($FILETIME[3]) << 24);
    22.      $high =
    23.           (ord($FILETIME[4])) |
    24.           (ord($FILETIME[5]) << 8) |
    25.           (ord($FILETIME[6]) << 16) |
    26.           (ord($FILETIME[7]) << 24);
    27.  
    28.     $f64 = (int2float($high) * $x32 + int2float($low)) / 10000000;
    29.     return (int)($f64 - $sec_btw_epoch);
    30.   }
    31.  
     
  6. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк