Windows の FILETIME 構造にはうるう秒が含まれていますか?
-
02-07-2019 - |
質問
の FILETIME
構造 Microsoft のドキュメントによると、1601 年 1 月 1 日 (おそらくその日の始まり) からカウントされますが、これにはうるう秒が含まれますか?
解決
問題は次のようなものであってはなりません FILETIME
うるう秒も含まれます。
そのはず:
人、関数、ライブラリが解釈を行います。
FILETIME
(すなわち、FileTimeToSystemTime
) 継続時間をカウントするときにうるう秒は含まれますか?
簡単な答えは、 "いいえ". FileTimeToSystemTime
秒を次のように返します 0..59
.
より簡単な答えは次のとおりです。」もちろんそうではありません。どうしてそんなことができるでしょうか?".
私の Windows 2000 マシンは、リリース以来 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
Q.E.D.
元の投稿者は気に入らないかもしれませんが、神は意図的に、1 年が 1 日で割り切れないように調整しました。彼はプログラマーを台無しにするためだけにそれをしたのです。
他のヒント
ここその特定の日付が選択された理由についての詳細情報。
Filetime構造は、1601年1月1日以降、100ナノ秒間隔の形で時間を記録します。なぜその日付が選ばれたのですか?
グレゴリオカレンダーは400年のサイクルで動作し、1601はWindows NTが設計されている時点でアクティブだったサイクルの最初の年です。言い換えれば、数学をうまく出させるために選ばれました。
私は実際にデイブ・カトラーからこれを確認しているメールを持っています。
最初に次のことを決定することなしに、この質問に対する唯一の答えはありません。Windows の FILETIME は実際に何をカウントしていますか?Microsoft のドキュメントには、UTC 1601 から 100 ナノ秒間隔をカウントすると記載されていますが、これには問題があります。
1960 年以前には、国際的に調整された時刻の形式は存在しませんでした。UTC という名前自体は、1964 年より前の文献には存在しません。公式名称としての UTC という名前は 1970 年まで存在しませんでした。しかし事態はさらに悪化します。王立グリニッジ天文台が設立されたのは 1676 年であるため、FILETIME を GMT として解釈しようとしても明確な意味はなく、正確な脱進機を備えた振り子時計が 1 秒の精度を出し始めたのもその頃でした。
FILETIME が平均太陽秒として解釈される場合、UT にはうるう秒がないため、1601 以降のうるう秒の数はゼロになります。FILETIME が原子クロノメーターが存在していたかのように解釈される場合、1601 年以降の閏秒数は約 -60 になります (つまり、マイナス 60 閏秒です)。
それは古代の歴史ですが、原子クロノメーター以降の時代はどうでしょうか?各国政府が平均太陽秒とSI秒を区別していないため、これはさらに良いことではありません。ITU-R は 10 年にわたり、うるう秒の廃止について議論してきましたが、国際的なコンセンサスは得られていません。その理由の一部は、このページのJavaScript (古代史のプロットについては、そのページのデルタ T リンクも参照してください)。各国政府は明確な区別をしていないため、1972 年以降の秒数を定義しようとする試みは、一部の管轄区域の法律に従って無効になる危険性があります。ITU-R の代表者は、POSIX 委員会のメンバーと同様に、この複雑さを認識しています。外交問題が解決するまで、各国政府や国際標準が平均太陽秒とSI秒を明確に区別し、選択するまでは、コンピュータ標準が追随できる見込みはほとんどない。
うるう秒は IERS によって予期せず追加されます。UTC とうるう秒が定義された 1972 年以来、23 秒が追加されています。ウィキペディアには、「地球の自転速度は長期的には予測できないため、その必要性を半年以上前に予測することは不可能である」と書かれています。
うるう秒が挿入されたときの履歴を保持し、うるう秒が挿入されたときの参照を維持するために OS を更新し続ける必要があり、その差が非常に小さいため、汎用 OS に期待しないのは当然です。うるう秒を補正します。
さらに、UTC と比較した PC の単純な電子時計の通常の時計のずれは、うるう秒に必要な補正よりもはるかに大きくなります。うるう秒を補正するような精度が必要な場合は、非常に不正確な PC クロックを使用すべきではありません。
この質問に対する答えは以前は「いいえ」でしたが、次のように変わりました。 はい、ある意味、時々...
当たり Windows ネットワーキング チームのブログ記事:
Server 2019 および Windows 10 October [2018] 更新時間 API 以降、FILETIME を SystemTime に変換するときに、オペレーティング システムが認識しているすべてのうるう秒が考慮されるようになりました。
この機能が追加されて以来、うるう秒は発行されていないため、オペレーティング システムはまだうるう秒を認識していません。ただし、次の公式のうるう秒が世に出ると、この新機能が有効になっている Windows コンピュータはそれを追跡することになります。 FILETIME
値は、解釈時にコンピュータ上のうるう秒の数によってオフセットされます。
ブログ投稿ではさらに次のように説明されています。
FILETIME には変更は加えられません。これは、エポックの開始以降の 100 ns 間隔の数を表します。変更されたのは、その数値を SYSTEMTIME に変換したり逆に変換したりするときの解釈です。影響を受ける API のリストは次のとおりです。
- システム時刻の取得
- ローカルタイムを取得する
- ファイル時間からシステム時間まで
- ファイル時間からローカル時間まで
- システム時間からファイル時間まで
- SetSystemTime
- ローカルタイムを設定する
このリリースより前のリリースでは、SYSTEMTIME の wSecond の有効な値は 0 ~ 59 でした。SYSTEMTIME は、年、月、日がうるう秒が有効な日を表す場合、値 60 を許可するように更新されました。
...
SYSTEMTIME 構造で 60 秒を受け取るには、プロセスは明示的にオプトインする必要があります。
オプトインは、方法にリストされている機能内の動作に適用されることに注意してください。 FILETIME
にマッピングされます SYSTEMTIME
. 。オプトインするかどうかに関係なく、オペレーティング システムは依然としてオフセットします。 FILETIME
認識しているうるう秒に応じた値。
互換性に関して、記事では次のように述べられています。
サードパーティのフレームワークに依存するアプリケーションは、Windows 上のフレームワークの実装も正しい API を呼び出して正しい時刻を計算していることを確認する必要があります。そうしないと、アプリケーションは間違った時刻を報告します。
また、へのリンクも提供します 以前の投稿 ここでは、次のように機能全体を無効にする方法について説明します。
...次のレジストリ キーを追加することで、以前のオペレーティング システムの動作に戻し、うるう秒を全面的に無効にすることができます。
HKLM:\SYSTEM\CurrentControlSet\Control\LeapSecondInformation
- タイプ:「REG_DWORD」
- 名前:有効
- 価値:
0
システム全体の設定を無効にします- 価値:
1
システム全体の設定を有効にします次に、システムを再起動します。
非常に大雑把な要約:
UTC = (原子時) + (うるう秒) ~~ (平均太陽時)
MS のドキュメントには、特に「UTC」と記載されているため、うるう秒を含める必要があります。MS の場合と同様、走行距離は異なる場合があります。
これによれば コメント Windows はうるう秒をまったく認識しません。今日の 1:39:45 を表す FILETIME に 24 * 60 * 60 秒を加算すると、何があっても明日の 1:39:45 を表す FILETIME が得られます。