0

I have a windows filetime (for example, 132522078890080000)

In Python I easily can convert it like that. Result is 1607716289 (Sat Dec 12 2020 00:51:29 GMT+0500 (Yekaterinburg Standard Time)). That's right!

But in C++ I tried to convert it like that

#include <iostream>
#include <ctime>


#define WINDOWS_TICK 10000000
#define SEC_TO_UNIX_EPOCH 11644473600LL

uint64_t WindowsTickToUnixSeconds(uint64_t windowsTicks)
{
  return (uint64_t)(windowsTicks / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
}

int main() {
  const uint64_t in_raw = 132522078890080000;
  auto unix_timestamp = WindowsTickToUnixSeconds(in_raw);
  time_t out = unix_timestamp;
  std::cout << "Timestamp: " << unix_timestamp << std::endl;
  std::cout << "Local: " << asctime(localtime(&out)) << std::endl;
  std::cout << "GMT: " << asctime(gmtime(&out)) << std::endl;
  return 0;
}

And result of that is

Timestamp: 1607734289
Local: Sat Dec 12 05:51:29 2020

GMT: Sat Dec 12 00:51:29 2020

As you can see the timestamps are different (1607734289, 1607716289, difference is 5 hours (because timezone is Asia/Yekaterinburg)).

I can easily subtract 5 hours but in that case it won't work in another timezone.

So how can I get correct timestamp?

Able Arthy
  • 11
  • 2
  • 1
    Windows `FILETIME` is the number of 100-nanosecond intervals since 1601-01-01 00:00:00 UTC. Unix timestamp is the number of seconds since 1970-01-01 00:00:00 UTC. Thus, for the `FILETIME` value `132522078890080000`, the correct Unix timestamp is `1607734289`. The value `1607716289` you mention, is incorrect because Unix timestamp is based on UTC, not on local time zone. – heap underrun Feb 13 '21 at 10:42
  • "_in C++ I tried to convert it like_" - That doesn't have anything to do with C++ but has everything to do with the operating system. Why not use [`std::chrono::file_clock`](https://en.cppreference.com/w/cpp/chrono/file_clock) to get similar high level support as you have in python? – Ted Lyngmo Feb 13 '21 at 10:52
  • Comment on my own comment: I see why you don't use `file_clock` - VS2019 doesn't have full C++20 support just yet. – Ted Lyngmo Feb 13 '21 at 11:28
  • @heapunderrun, I got that FILETIME value from the program and the time that was expected is 1607716289 (incorrect as you said. also checked this on one site). So the value I get from the program is wrong? And is it not in my area of responsibility? And why python script transform time as I want (i.e. 1607716289)? – Able Arthy Feb 13 '21 at 11:50
  • Windows `FILETIME` values are *supposed* to always be in terms of UTC, but unfortunately that is not always the case. For example, Windows also provides [`FileTimeToLocalFileTime`](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-filetimetolocalfiletime) and [`LocalFileTimeToFileTime`](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-localfiletimetofiletime) functions. You could use one of those to adjust your timestamp, but first I'd ask where you got that initial value from? Why is it not UTC based in the first place? – Matt Johnson-Pint Feb 13 '21 at 19:01
  • @MattJohnson-Pint thanks for that functions. That's what I've been looking for. The program returns `Local FILETIME` and I should convert it. As I use Linux I've tried to find implementation of that functions. [That](https://doxygen.reactos.org/d5/dac/dll_2win32_2kernel32_2client_2time_8c.html#ada3d350b19133a582dd651be24b88428) is what I found. But what if I need to convert `130468320000000000` (9|10) June 2014. Will it take into account DST? – Able Arthy Feb 14 '21 at 10:06
  • Again - where did you get it from? *How* did the program return a local filetime? Yes, the function is designed to take DST into account, but I can only speak for the Windows implementation. I have no idea about ReactOS or any other implementation. – Matt Johnson-Pint Feb 15 '21 at 17:51
  • Also, because of DST, you can't reliably just subtract after the conversion. The offset to apply must be determined *before* adjusting to Unix time. The `LocalFileTimeToFileTime` function does that correctly, but it can be really tricky to implement yourself. You're better off correcting the source to ensure it is a UTC-based filetime up front. – Matt Johnson-Pint Feb 15 '21 at 17:55

0 Answers0