让应用在另一个时区运行
落在错误日期的报表、提前一小时响起的提醒、读起来像是明天的时间戳——这些问题大多只会出现在你自己并不身处的时区里。这个工具给一个进程单独的偏移量,而你的系统时区原封不动。
为什么常见的办法帮不上忙
- 修改 Windows 时区会改动所有东西——你的日历、你的日志、你的会议——而在受管理的机器上,这也许根本不由你来改。
- 设置
TZ对一些运行时有效,对另一些无效。读取GetTimeZoneInformation的原生 Windows 应用完全不会察觉。 - 浏览器开发者工具可以覆盖网页的时区,这很好,但与桌面应用无关。
一个进程,一个偏移量
会话带有自己的偏移量。应用向 Windows 询问自己处于哪个时区,得到的就是这个答案,而机器上的其他所有程序得到的是真实的答案。
# 同一个时刻,从美国西海岸看过去 chrono run "C:\apps\test.exe" --at 2027-01-15T09:00:00 --zone -08:00 # 只改时区——今天的真实日期,别人的时钟 chrono run "C:\apps\test.exe" --zone +09:00
计算器回答问题的另一半——某个时刻在别处实际读作什么。转换会保持时刻不变,只改变墙上时钟,一个日期落在错误的一天,恰恰就是这么发生的:
$ chrono calc --base 2027-01-15T09:00:00 --zone +01:00 --to-zone -08:00 Chrono Mock - date calculator base: 2027-01-15T09:00:00 step 1: zone -08:00 -> 2027-01-15T00:00:00 result: 2027-01-15T00:00:00 formats: ISO date 2027-01-15 ISO datetime 2027-01-15T00:00:00-08:00 US 01/15/2027 PL 15.01.2027
中欧的上午九点,在美国西海岸是午夜。同一个时刻,而按本地日期分组的日报,会因为运行的位置不同而把它归到不同的一天。
如实说明的局限,在这里尤其重要
会话时区是没有夏令时的固定偏移量。
设为 +01:00 的会话,无论它的时钟读到的是一月还是七月,都停留在 +01:00。因此,跨越真实切换的运行,会与该时区实际显示的时间相差一小时,而让应用经历夏令时切换,目前还不是这个工具能做的事。日期计算器会如实说明这一点,而不是猜测。
- 该时区会把自己报告为“Chrono Session”,这是任何 Windows 注册表都不认识的名字。凡是把这个名字映射回时区的东西——包括 .NET 的
TimeZoneInfo.Local——都会退回到使用偏移量,这是正确的答案。坚持要用注册表中名称的应用则找不到。 - Java 会把会话时区当作偏移量来接收。会话时区没有夏令时,背后也没有城市,所以 Java 用它的偏移量来命名——对于 +05:30 的会话就是
GMT+05:30。 - 在 Chromium 和 Electron 模式下,页面同样读取会话时区。它是同一个固定偏移:每个页面和 worker 都会被放到这个时区,并检查自己读到的值。Electron 应用的主进程在 Node 中运行 JavaScript,会话无法触及,所以它保持真实时钟。
- 偏移量的范围是 -14:00 到 +14:00,以整分钟为单位。超出这个范围的值会被拒绝,而不是悄悄回绕。
其中哪一条适用于你的应用,是可以测量的,而不是靠猜。 会话会报告它自己的覆盖情况 →