5

もう一度WindowsからLinuxに移行します。NTP時間を計算する関数をWindowsからLinuxに移植する必要があります。シンプルに見えますが、フォーマットはWindowsFILETIMEフォーマットです。私は違いが何であるかについてある程度の考えを持っていますが、これまでのところ、Linux時間をWindowsFILETIME形式に正しく変換することはできません。誰かがこれを行う方法について何かアイデアがありますか?

これを行う方法に関する記事をいくつか見ましたが、それらはすべてWin32関数を使用しており、使用できません。これが意味をなさない場合は、Windowsコードを投稿できます。

また、現在の時刻を取得し、1900年1月1日から減算して、NTPを見つけるためのデルタを取得します。Linuxでは、

const unsigned long EPOCH   = 2208988800UL

この結果を得るために私の時間に?

4

3 に答える 3

10

構造に関するMicrosoftのドキュメントでは、FILETIME構造について説明しています。基本的な考え方は、Windowsは1601年1月1日から10〜7FILETIME秒(100ナノ秒間隔)のステップでカウントするというものです(なぜ1601?わからない...)。Linuxでは、を使用して1970年1月1日からマイクロ秒(10 -6 )で時間を取得できます。したがって、次のC関数がその役割を果たします。gettimeofday()

#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;
}
于 2010-11-09T14:50:46.833 に答える
5

まず、なぜ1601なのか?グレゴリオ暦は400年ごとに繰り返され、先発グレゴリオ暦は0001-01-01で始まるためです。したがって、1601は1980年(1970年、...)より前の最後のサイクル開始であり、計算が単純化されます。(ああ、それが第3ミレニアムが2000-01-01ではなく2001-01-01に始まった理由です...)

FILETIMEからの2進分数を使用してNTPタイムスタンプのようなものを作成するには、

  1. LONGLONGまたはULONGLONGを使用してFILETIMEの目盛りを表すことにより、エポックの原点をシフトします。
  2. ティックを10^7でフロア分割して、秒(商として)と分数(余りとして)を取得します。純粋に符号なしで計算する場合は、単純に除算します。ただし、その場合は負の値を表すことはできません。
  3. 符号なしは、64ビットの小数部(> = 0である必要があります)に1844674407371ull(2 ^ 64/10 ^ 7(四捨五入))を掛けます。
  4. 製品の上位32ビットをNTPタイムスタンプの2進小数として使用します。(製品の下位32ビットから丸めることができます。小数ティックが10 ^ 7未満に厳密である限り、1秒への丸めキャリーは発生しないことに注意してください。)
于 2013-09-18T10:50:14.287 に答える
2

一部のWebサイトを廃棄してタイムスタンプ値を取得するとします。あなたが定義する

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);
于 2017-01-03T12:13:57.177 に答える