Microsoft のドキュメントによると、このFILETIME
構造は 1601 年 1 月 1 日 (おそらくその日の始まり) からカウントされますが、これにはうるう秒が含まれますか?
7 に答える
FILETIME
うるう秒が含まれているかどうかは問題ではありません。
そのはず:
FILETIME
(つまり)を解釈する人、関数、およびライブラリにはFileTimeToSystemTime
、期間を数えるときにうるう秒が含まれていますか?
簡単な答えは「いいえ」です。FileTimeToSystemTime
秒をとして返します0..59
。
より簡単な答えは、「もちろんそうではありませんが、どうすればよいでしょうか?」です。
私のWindows2000マシンは、リリースされてから10年間にうるう秒が2秒追加されたことを認識していません。それが行う解釈FILETIME
は間違っています。
最後に、論理に頼るのではなく、直接の実験的観察によって、ポスターの質問に対する答えを決定することができます。
var
systemTime: TSystemTime;
fileTime: TFileTime;
begin
//Construct a system-time for the 12/31/2008 11:59:59 pm
ZeroMemory(@systemTime, SizeOf(systemTime));
systemtime.wYear := 2008;
systemTime.wMonth := 12;
systemTime.wDay := 31;
systemTime.wHour := 23;
systemtime.wMinute := 59;
systemtime.wSecond := 59;
//Convert it to a file time
SystemTimeToFileTime(systemTime, {var}fileTime);
//There was a leap second 12/31/2008 11:59:60 pm
//Add one second to our filetime to reach the leap second
filetime.dwLowDateTime := fileTime.dwLowDateTime+10000000; //10,000,000 * 100ns = 1s
//Convert the filetime, sitting on a leap second, to a displayable system time
FileTimeToSystemTime(fileTime, {var}systemTime);
//And now print the system time
ShowMessage(DateTimeToStr(SystemTimeToDateTime(systemTime)));
に1秒を追加
12/31/2008 11:59:59pm
与える
1/1/2009 12:00:00am
それよりも
1/1/2009 11:59:60pm
QED
オリジナルのポスターは気に入らないかもしれませんが、神は意図的にそれを装備して、1年が1日で均等に割り切れないようにしました。彼はプログラマーを台無しにするためだけにそれをしました。
その特定の日付が選択された理由についての詳細を次に示します。
FILETIME 構造体は、1601 年 1 月 1 日から 100 ナノ秒間隔で時間を記録します。なぜその日付が選ばれたのでしょうか?
グレゴリオ暦は 400 年周期で動作し、1601 年は Windows NT が設計された時点でアクティブだった周期の最初の年です。言い換えれば、数学をうまく出すために選ばれたのです。
私は実際にこれを確認する Dave Cutler からの電子メールを持っています。
うるう秒は、IERSによって予期せず追加されます。UTCとうるう秒が定義された1972年以降、23秒が追加されました。ウィキペディアは、「地球の自転速度は長期的には予測できないため、6か月以上前に地球の自転の必要性を予測することはできません」と述べています。
うるう秒が挿入されたときの履歴を保持し、うるう秒が挿入されたときの参照を保持するようにOSを更新し続ける必要があり、その差が非常に小さいため、汎用OSがうるう秒を補正します。
さらに、UTCと比較したPCの単純な電子時計の通常のクロックドリフトは、うるう秒に必要な補正よりもはるかに大きくなります。うるう秒を補正するための精度が必要な場合は、非常に不正確なPCクロックを使用しないでください。
このコメントによると、ウィンドウはうるう秒をまったく認識していません。今日の1:39:45を表すFILETIMEに24*60 * 60秒を追加すると、何があっても、明日の1:39:45を表すFILETIMEが得られます。
非常に大雑把な要約:
UTC =(原子時)+(うるう秒)~~(平均太陽時)
MSのドキュメントには、具体的には「UTC」と記載されているため、うるう秒を含める必要があります。MSの場合と同様に、マイレージは異なる場合があります。