我再次从Windows转向Linux,我必须将一个从Windows移植到Linux的功能来计算NTP时间。看似简单但格式为Windows FILETIME格式。我有点想知道差异是什么,但到目前为止我无法正确地将我的Linux时间转换为Windows文件时格式。有没有人对如何做到这一点有任何想法?
我看过一些关于如何做到这一点的文章但他们都使用win32函数,我不能使用它们!如果没有意义,我可以发布Windows代码,谢谢。
他们还花费当前时间并从1900年1月1日减去它以获得增量找到NTP,我认为在Linux中我只是将const unsigned long EPOCH = 2208988800UL添加到我获得此结果的时间?
感谢。
答案 0 :(得分:8)
FILETIME
结构的Microsoft文档解释了它的含义。基本思想是Windows FILETIME
从1601年1月1日起以10 -7 秒(100纳秒间隔)的步长计算(为什么1601?不知道......)。在Linux中,您可以使用gettimeofday()
从1970年1月1日起以微秒(10 -6 )获得时间。因此,以下C函数完成了这项工作:
#include <sys/time.h>
/**
* number of seconds from 1 Jan. 1601 00:00 to 1 Jan 1970 00:00 UTC
*/
#define EPOCH_DIFF 11644473600LL
unsigned long long
getfiletime() {
struct timeval tv;
unsigned long long result = EPOCH_DIFF;
gettimeofday(&tv, NULL);
result += tv.tv_sec;
result *= 10000000LL;
result += tv.tv_usec * 10;
return result;
}
答案 1 :(得分:3)
首先,为什么1601?因为公历每400年重复一次,而公历日历从0001-01-01开始。所以1601是1980年之前的最后一个循环开始(1970年......),这简化了计算。 (哦,这就是为什么第三个千年在2001-01-01开始,而不在2000-01-01 ......)
使用来自FILETIME的二进制分数创建类似NTP时间戳的内容,
答案 2 :(得分:1)
假设您从废弃某个网站获取时间戳值。你定义
unsigned __int64 timestamp = 0;
您获取的值可能需要除以1000。
if (element.HasMember(L"timestamp"))
{
timestamp = element[L"timestamp"].GetUint64() / 1000;
} }
然后你这样做:
LONGLONG ll;
ll = Int32x32To64(timestamp, 10000000) + 116444736000000000;
FILETIME ft;
ft.dwLowDateTime = (DWORD)ll;
ft.dwHighDateTime = ll >> 32;
SYSTEMTIME stTime;
FileTimeToSystemTime(&ft, &stTime);