2010-08-27 198 views
3

我再次從Windows轉到Linux,我必須將一個函數從Windows移植到Linux來計算NTP時間。看起來很簡單,但格式是Windows FILETIME格式。我有點想法是什麼區別,但到目前爲止,我無法正確地將我的Linux時間轉換爲Windows文件時間格式。有沒有人有任何想法如何做到這一點?將Unix/Linux時間轉換爲Windows FILETIME

我已經看到一些關於如何做到這一點的文章,但他們都使用win32函數,我無法使用它們!如果這沒有意義,我可以發佈Windows代碼,謝謝。

他們也採取當前的時間,並從1900年1月1日減去它來獲得三角洲找到NTP,我會假設在Linux中,我只是將const unsigned long EPOCH = 2208988800UL添加到我的時間來得到這個結果?

謝謝。

+0

我有一個工作轉換,但現在的問題是,我需要微秒的分辨率。如果任何人有興趣,我可以發佈代碼,但現在我堅持在幾秒鐘內。 – 2010-08-31 13:42:30

回答

7

FILETIME結構的Microsoft文檔解釋了它是什麼。基本思想是,1601年1月1日(爲什麼1601?不知道......)的步驟10 -7秒(100-ns間隔)計算Windows FILETIME。在Linux中,您可以從1   Jan   1970使用gettimeofday()獲得以微秒爲單位的時間(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

1601因爲1600將是一個閏年,而商業決定背後「我們是否應該添加代碼來正確處理日期在1600年1月/ 2月的日期,還是簡單地從1601年開始?」非常明顯。 – 2012-04-03 10:18:51

+0

那麼,爲什麼不是1605年,1609年......但是1601年呢? – Tebe 2012-12-22 19:37:57

2

首先,爲什麼1601?由於公曆每400年重複一次,而預先公佈的格列高利曆從0001-01-01開始。所以1601是1980年以前的最後一個週期(1970,...),這簡化了計算。 (哦,這就是爲什麼第三個千年在2001-01-01開始,而不是在2000-01-01 ...)

要創建類似於FILETIME的二進制分數的NTP時間戳,

  1. 移位劃時代的起源,使用LONGLONG或ULONGLONG到 表示FILETIME的蜱。
  2. 以10^7爲單位進行滴答的底部劃分以得到秒(如 商)和分數(作爲餘數)。如果你純粹以無符號的方式計算 ,只需簡單地劃分。但在這種情況下,您不能表示負值 值。
  3. 無符號乘法的分數(其必須> = 0)在64位由 1844674407371ull,其值爲2 ^10分之64^ 7(圓形)
  4. 以產品的高32位作爲二進制分數 NTP時間戳。 (您可能希望從 產品低32位四捨五入。請注意,四捨五入進位全秒不能 發生,只要分數蜱嚴格低於10^7)
+0

這是問題的反面,但非常有用,謝謝。 – Rob 2014-11-11 12:40:04

0

假設你從廢除某個網站獲取時間戳值。您可以定義

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); 
+0

https://msdn.microsoft.com/en-us/library/windows/desktop/ms724228(v=vs.85).aspx – 2017-10-22 20:12:35

+0

謝謝@NathanMoinvaziri – 2017-10-26 13:13:23