去**的人类计时系统

Last updated on August 22, 2023 pm

本文主要内容翻译并整理自Falsehoods Programmers Believe about Time


以下所有假定都是错的。*。
Calendaring is hard. 但都是tm人为的。
所以不要指望人类社会有多有序。看完下文,你连现在自己活在几时几刻都不知道。

标准确定

  • 时间没有开始也没有终结。(2038问题)

  • 时间的最小单位是1s。(No)
  • ……行吧1ms。(物理学上最小的时间单位是一普朗克时间,约$5.39116\times10^{-44}$秒,而实际应用中精确到纳秒的计算也被大范围使用(比如统计cpu寄存器的读写速率))

  • 每分钟总有60秒。(闰秒)
  • ……那起码差距不会太大吧。(20年后冷启动的集群)
  • ……那至少我的一分钟不可能比别人的一小时还长吧。(一个特殊情景:VM被Host临时Suspend,但是没有去通知系统时钟这个操作,导致恢复之后系统时钟自己count的一分钟远远长于其他机器的一小时)
  • 别逗了。(哪可能啊!)(是的,这不是假想,是早期KVM存在的一个真实bug)

  • 一天从早晨开始。(犹太历的一天从日落开始。我开始理解希特勒了。(这句真的是玩笑))
  • 每天总有24小时。(取决于语境,“刚好”等于24小时整的有例外,比如闰秒日)

  • 同时只会使用一个历法系统。(英帝国改历,见下)

  • 一周从周一开始。(不言而喻)
  • 周六之前永远是周五。(Samoa改元。我服了。)
  • 一周肯定有周六和周日。(中东的阿拉伯地区的周末是周五和周六。写的我都犯迷糊)

  • 每月只有30或31天。(2月)
  • ……那每月只可能有28、29、30、31天。(公历1752年的9月,英帝国从儒略历改入格里高利历,该月3-13日被跳过,所以该月少了11天。哈哈,历史真搞笑。
  • 2月总有28天。(闰年的2月有29天)

  • 每年总有365天。(闰年有366,当然还有英帝国改历)

  • 每跨24小时,这一时间段的开头或者结尾总在同一天(或者同一周、同一月)。(不言自明)
  • 每周的开头和结尾总在同一月。(不言自明)
  • 每周/月的开头和结尾总在同一年。(同上)
  • 同一个月在哪里都有同样的天数。(在改历期间英帝国属于比较靠后的)
  • 一个月里的日期总是递增的。(见上)

  • 每个能除以4的年份都是闰年。(如果是100的倍数但不是400的倍数,那么该年为平年。因此,格里高利历相对于儒略历每400年少3个闰年)
  • 不是闰年的年份永远不会有闰日。(哦对,这个要“谢谢”微软的向前兼容

  • 时区之间的时差应该是一定的。(1小时最常见,但有半小时的半时区,甚至有+20/-10分钟这种极端的奇葩,并且人家也是时区)
  • ……那至少是半小时的整数倍吧。(见上)
  • ……15分钟呢。(见上)
  • ……那忽略掉DST秒总行了吧。(哦,更有趣。Calcutta Time直到1948年之前都是UTC+5:53:20。)
  • ……那不可能超过一个小时吧(也就是说,飞过国际日界线时不需要检查飞机的导航系统)。(你猜这个问题导致了多大损失。没错,让一架F22空中停车。
  • ……那除去历史原因,至少未来时差不会变了吧。(非洲某些国家打一仗改一个元还需要提吗)
  • ……那至少改变前会有足够的关注吧。(这里是 微软公布DST和时区更改的博客 ,你知道吗)
  • ……那至少可以从所在城市推断出时区——都这么精确了不可能错了吧。(巧了,例子到家门:新疆省乌鲁木齐市,汉族居民使用北京时间,维吾尔族居民使用当地时间,所以当地是Asia/Beijing和Asia/Urumqi并行)

  • 夏令时每年定时实行。(见上博客,各个国家改这玩意不知道有多乱)
  • ……那在每个时区实现的时间都一致。(见上,我就不理解斐济岛有什么好实行夏令时的)
  • 夏令时总是会调整一个小时。(见上)
  • 当地与UTC的时差不会在办公时间发生。(那些下午7点改DST的政权真的可以去死一死了)

  • 假期总是整数天。(同上犹太历,从一天晚上到第二天晚上;当然,多少人高中没放过半天假期呢)

表示与表达

  • 时间戳总会是一个常见易懂的值比如Unix timestamp。(见ISO 8601,你永远不会知道你会见到什么神经病的表示法)
  • 时间戳总会是一个恒定的格式。(同上)
  • 肯定不会有像 ---12Z 或者 P12Y34M56DT78H90M12.345S的日期时间格式吧。(同上)

  • 每一个整数都是一个可能的年份。(公元,没有0年。基本上哪个历法都没有。)
  • 人类可读的日期可以用统一的格式来给出。(世界:2位年/2位月/2位日;4位年/2位月/2位日;某些国家:月/日/年;某些奇葩:日/月/年)
  • 显示的时间和存储的时间的秒肯定是一样的。(呵)
  • ……那年总是了吧。(千年虫/2-2-2日期表示法)

  • GMT和UTC是同一个时区系统。(格林尼治平时和协调世界时可真的不一样。微软的文档都指示尽最大可能不用GMT表示时间。)
  • 24:12:34肯定是个无效的时间。(关注ACG文化的你肯定知道——在日本,我们用三十小时制!!!厉害吧!!!)

同步问题

  • 跑程序的机器总会在GMT时区系统里。(如果你要为ISS或者火星Rover写程序的话,……)
  • ……那至少跑程序的机器总会在“同一个”时区里。(比如长航线飞机的GPS导航,比如同上)

  • 系统时钟总会设置成当地的正确时间。(不言自明)
  • ……那误差不可能太大。(20年之后冷启动的集群)
  • ……那至少误差是一个恒定的值。(提供时钟频率的晶振误差)
  • 没有必要把系统时间设成正确的当地时间之外的任何值。(测试)
  • ……那生产环境不需要吧。(对于比如全球性金融平台这种,UTC等更为常见)

  • 服务端与客户端的时间肯定一致。(不言自明)
  • ……那至少不会差太大。(见12)
  • ……那总不能差出几十年吧。(32位机过了2038问题后重新对时,虽说没什么意义)
  • ……还不对的话至少误差恒定吧。(见13)

  • 服务端和客户端的时区肯定一致。(不言自明)

  • 系统时钟不可能设在老远的过去或者老远的将来。(测试目的,比如提前体验2038问题;并且为了长期开发考虑的话你总会碰到这个未来)

计算

  • 从某个特定日期和时间开始后推特定时间段可以很容易的推出一个确定的日期和时间。(老样子,“谢谢”各个国家混乱的DST政策。谁知道推到的终点到时候会不会有DST)
  • 能算出什么时候会加闰秒。(那您就是上帝了呢)

  • Thread.sleep(1000) 休眠1000ms。
  • Thread.sleep(1000) 休眠小于等于1000ms。

(引自微软文档:

The system clock ticks at a specific rate called the clock resolution. The actual timeout might not be exactly the specified timeout, because the specified timeout will be adjusted to coincide with clock ticks.

yeah.)

Unix时间您这边请

  • Unix时间是自1970年1月1日起的秒数。(它忽略闰秒)
  • Unix时间除了秒什么都不管。(其实吧,它连秒都不是很准确。POSIX标准要求每天Unix时间必须递进86400s,完全忽略闰秒)

时间戳

  • 时间戳的精度总是一致。(取决于应用类型)
  • 精度足够的时间戳可以被安全的认为是唯一的(实际上就是认为时间单调)。(见负闰秒)
  • 时间戳代表事件真实发生的时间。(不言自明,寄存器读写都要时间那在一个事件发生后生成时间戳更得需要时间了)

其他

  • 时间在山峰和山谷的流速一致。(狭义相对论——不解释)

去**的人类计时系统
http://elfile4138.moe/2022/07/去-的人类计时系统/
Author
Matrew File
Posted on
July 29, 2022
Updated on
August 22, 2023
Licensed under