現在の時刻を印刷…うるう秒を考慮に入れて


9

(注:関連ものの、この課題は、の重複ではありませんこの1、それは自分の時間を自動的にうるう秒を決定するのではなくハードコーディングする必要があるため、との重複ではありませんこの1難易度のほとんどは、うるう秒スキューなしで時間を決定するから来ているので、 、ほとんどの場合APIがデフォルトで実行しないものです。そのため、ソリューションは、これらの課題のいずれかのソリューションとは異なる可能性があります。

2016年の終わりに近づいていますが、ほとんどの人が予想するよりも少し長くかかります。それでは、今年の追加秒数を祝う挑戦です。

現在の時刻をUTCで時間、分、秒として出力します。(たとえば、正午の正規の出力フォーマットには、12:00:00とが含ま[12,0,0]れます。ここでは、フォーマットはそれほど重要ではありません。)

ただし、ひねりがあります。プログラムはうるう秒を過去と未来の両方で適切に処理する必要があります。これは、プログラムがオンラインまたは自動的に更新/更新可能なソースからうるう秒のリストを取得する必要があることを意味します。必要に応じて、インターネットに接続してこれを取得できます。ただし、このチャレンジより前のURL(つまり、プログラムの一部を他の場所からダウンロードしない)にのみ接続でき、接続を使用して現在の時刻を特定することはできません(特に、アクセスしようとしてもプログラムは機能する必要があります)インターネットは最長24時間古いページを返します)。

現在のほとんどのオペレーティングシステムのデフォルトAPIは、他の方法では混乱する可能性のあるプログラムからそれらを隠すために、うるう秒あたりの時間をゆがめます。そのため、この課題の主な難点は、それを元に戻すメソッドまたはAPIを見つけ、UTCで変更されていない真の現在時刻を計算することです。

理論的には、プログラムが無限に高速なコンピューターで実行された場合、プログラムは完全に正確である必要があり、実行に意図的にゼロ以上の時間をかけてはなりません。(もちろん、実際には、プログラムは不完全なコンピューター上で実行されるため、おそらく瞬時には実行されません。これが結果を無効にすることを心配する必要はありませんが、プログラムの正確さをそれに依存してはなりません。 )

システムクロックがどのタイムゾーンに設定されているかに関係なく、プログラムは機能する必要があります。(ただし、使用されているタイムゾーンについてオペレーティングシステムまたは環境からの情報を要求する場合があり、応答が正確であると想定する場合があります。)

、最短プログラムが勝ちます。幸運を!


回答:


2

PowerShell、161バイト

(('{0:H:m:s}','23:59:60')[(($d=[datetime]::UtcNow).Ticks-6114960*98e9)/1e8-in((irm ietf.org/timezones/data/leap-seconds.list)-split'[^@]	|
'-match'^\d{9}')])-f$d

オンラインでお試しください!(ここでは動作しません、TIOは認識していないようだirmiwr、多分それはセキュリティ機能は?)

論理テスト(ハードコードされた日付):

(('{0:H:m:s}','23:59:60')[(($d=[datetime]'1/1/2017 00:00:00').Ticks-6114960*98e9)/1e8-in((irm ietf.org/timezones/data/leap-seconds.list)-split'[^@]	|
'-match'^\d{9}')])-f$d

ノート

正規表現文字列にはリテラルTABとリテラルの改行(0xA)があるため、それらをエスケープする必要はありませんでした(それぞれ1バイトを保存)。

説明

ietfファイルで(うるう秒の)指定された時間は、NTPエポックであるからの秒数です1/1/1900 00:00:00。Windowsでは、「ティック」は1ミリ秒の1ミリ秒(10,000,000ティック/秒)です。

整数を追加する[datetime]と、整数値はティックとしてカウントされるため、NTPエポックのハードコードされたティック値を使用して、現在のUTC時間のティック値から減算します(元の値は同時に割り当てられています)へ$d)。

ハードコードされたティック値を小さくするために、いくつかのゼロ(そのうちの9つ)を取り除いて98で割った後、98e9(98 * 10 9)を掛けます。

その減算の結果は、NTPエポック以降のティック単位の値です。それがで割った値を取得します1e8(ない1e9、現時点では明らかであろう理由のために)NTPエポック秒の値を取得する(ソートの)。実際には10倍小さくなります。

最初にドキュメントを行に分割してからタイムスタンプで行を処理するのではなく、IETFからドキュメントを取得しますTAB。タイムスタンプの後にあるため、改行と文字の両方で分割することにしました。ファイルに誤った行が1つあるため、それだけでは不要なタイムスタンプが追加されます。行は次のようになります。

#@	3707596800

だから私は正規表現を分割するように変更しました[^@]\t@その後にが続かない任意の文字TAB)。これはその行を除外するように機能しますが0、各タイムスタンプの最後を消費することにもなります。

私は除算だからこそ1e8なく1e9不足しているため、アカウントに、0

現在のタイムスタンプがチェックされ、去勢されたうるう秒のタイムスタンプのリスト内に存在することが確認されます。私が説明したこのプロセス全体は配列アクセサの内部にある[]ため、結果の[bool]値は0$false)または1$true)に合体されます。インデックスを作成する配列には、時間を表示するためのフォーマット文字列とハードコードされたの2つの要素が含まれてい23:59:60ます。前述の比較の真実性により、どちらが選択されるかが決まります。-fこれは、以前に割り当てられた現在の日付$dをパラメーターとして使用してフォーマット演算子に送られます。


これは、うるう秒の次の秒を何と表示しますか?うるう秒のロジックをたどることはできますが、どちらの側のロジックもたどることができるかはわかりません。(Windowsでは、うるう秒とそれに続く秒の両方が00:00:00として自然に表示されますか?)

@ ais523うるう秒の次の秒がシステム時刻として表示されます。Windowsはうるう秒を認識しないため、同期または手動設定で修正されるまで、クロックは1秒速くなります。禁止されている外部の時刻ソースを使用しないとシステム時刻が正しいかどうかを判断することができないため、要件を考えると、それを実際に調整することはできません。私ができる最善のことは、時刻を出力した後にNTP同期を強制するコードをこれに追加することです。これが許可されている場合でも、もちろん失敗する可能性があります(ネットワークエラー、タイムソースセットなしなど)。
ブライアンティスト、2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.