Как правильно преобразовать время Unix в FILETIME, используемое Win32

Microsoft предлагает следующую функцию в своем статья поддержки :

   // NOTE: this function is INCORRECT!
   void UnixTimeToFileTime(time_t t, LPFILETIME pft)
   {
     // Note that LONGLONG is a 64-bit value
     LONGLONG ll;
     ll = Int32x32To64(t, 10000000) + 116444736000000000;
     pft->dwLowDateTime = (DWORD)ll;
     pft->dwHighDateTime = ll >> 32;
   }

Однако, если время Unix «t» относится к датам после 2038 года, эта функция выдает неверный результат. Как заставить его нормально работать после 2038 года?


person Andrei Belogortseff    schedule 14.08.2018    source источник


Ответы (1)


Проблема заключается в использовании функции Int32x32To64, поскольку она усекает свои аргументы до 32 бит каждый. Если время unix превышает 32 бита (как это бывает с датами после 2038 года), это дает неверный результат. Чтобы исправить проблему, используйте 64-битное умножение вместо функции Int32x32To64:

   void UnixTimeToFileTime(time_t t, LPFILETIME pft)
   {
     // Note that LONGLONG is a 64-bit value
     LONGLONG ll;
     ll = t * 10000000I64 + 116444736000000000I64;
     pft->dwLowDateTime = (DWORD)ll;
     pft->dwHighDateTime = ll >> 32;
   }

Надеюсь, это сэкономит время кому-то.

person Andrei Belogortseff    schedule 14.08.2018