打印当前时间…考虑leap秒


9

(注:虽然相关的,这个挑战不是重复这一个,因为它需要自动确定闰秒,而不是硬编码的时间,而不是重复这一块,因为大部分的困难来自于确定时间没有闰秒歪斜,这是大多数时间API默认情况下都不会执行的操作。因此,解决方案看上去可能与针对其中任一挑战的解决方案有所不同。)

我们即将到2016年底,但所需时间将比大多数人期望的稍长。因此,这是今年庆祝我们获得第二名的挑战。

以UTC输出当前时间,以小时,分钟,秒为单位。(例如,正午的合法输出格式应包括12:00:00[12,0,0];此处的格式并不重要。)

但是,这有个不同之处:您的程序必须适当处理过去和将来的leap秒。这意味着您的程序将必须从一些在线或自动更新/可更新的源中获取of秒列表。如果愿意,您可以连接到Internet以获得此信息。但是,您只能连接到此挑战之前的URL(即,不能从其他位置下载程序的一部分),并且您不能使用该连接来确定当前时间(特别是:即使尝试访问,您的程序也必须运行)互联网返回的页面最多会过时24小时)。

当前大多数操作系统的默认API将使时间偏移leap秒左右,以便将它们从可能会造成混淆的程序中隐藏起来。因此,此挑战的主要困难是找到一种方法或API来撤消该问题,并找出UTC中真正未修改的当前时间。

从理论上讲,如果您的程序在无限快速的计算机上运行,​​则它应该是完全准确的,并且不得有意地花费超过零的时间来运行。(当然,实际上,您的程序将在不完美的计算机上运行,​​因此可能不会立即运行。您不必担心会导致结果无效,但不必依赖它来确保程序的正确性。 )

无论系统时钟设置为哪个时区,您的程序都必须运行。(但是,它可能会要求操作系统或环境提供有关正在使用哪个时区的信息,并可能假定答复是正确的。)

作为一个 ,最短的程序将获胜。祝好运!


Answers:


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个字节)。

说明

自NTP纪元以来,ietf文件中给定的时间(since秒)以秒为单位1/1/1900 00:00:00。在Windows上,“滴答”仅是百万分之一秒(10,000,000滴答/秒)。

如果在整数上加上一个整数,[datetime]它会将整数值记为滴答声,因此我使用的是NTP纪元的硬编码滴答声值,然后从当前UTC时间的滴答声值中减去它(同时为其分配原始值)到$d)。

为了使该硬编码的报价值更小,我删除了一些零(其中的9个)并除以98,然后乘以98e9(98 * 10 9)。

减法的结果是自NTP时代以来以滴答为单位的值。将该值除以1e8(不是1e9,因为一会儿就会明白),以秒为单位(以秒为单位),以获取自NTP时代以来的值。实际上,它会小10倍。

从IETF检索文档,而不是先将其拆分成几行,然后再处理带有时间戳的行,我决定在换行符和TAB字符上进行拆分,因为那是在时间戳之后。由于文件中只有一条错误行,因此仅此一项就将包含我们不希望的其他时间戳。该行如下所示:

#@	3707596800

因此,我更改了正则表达式以进行分割[^@]\t(任何不带@a的字符TAB),以排除该行,而且最终消耗了0每个时间戳中的最后一个。

这就是为什么我除以1e81e9,交代失踪0

检查当前时间戳,以查看其是否存在于已取消的leap秒时间戳列表中。我描述的整个过程都在数组访问器内部[],因此结果[bool]值合并为0$false)或1$true)。我们要索引到的数组包含两个元素:用于显示时间的格式字符串和hardcoded 23:59:60。上述比较的真实性确定了将选择哪个比较,并将其-f以先前分配的当前日期$d作为其参数输入到格式运算符中。


a秒之后,第二秒打印什么?我可以遵循逻辑for秒,但是不确定我可以遵循逻辑两次。(Windows是否自然地将a秒和其后的秒显示为00:00:00?)

@ ais523无论系统时间是多少,它将在display秒之后显示秒。Windows不知道leap秒,因此直到通过同步或手动设置纠正后,时钟才会快1秒。考虑到这些要求,我无法真正适应该要求,因为在不使用禁止的外部时间源的情况下,无法确定系统时间是否正确。我能做的最好的事情就是在代码上添加时间,以便在打印时间后强制NTP同步,如果允许的话,这当然可能会失败(网络错误,未设置时间源等)。
briantist
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.