在 Perl 6 中,所有 Instants 都是可比较的还是依赖于机器?

Are all Instants comparable or are they machine-dependent in Perl 6?

这是一个我能找到定义的案例,但我不太明白。来自 official documentation:

An Instant is a particular moment in time measured in atomic seconds, with fractions. It is not tied to or aware of any epoch.

我不明白你如何在没有纪元的情况下指定特定的时间?没有参考点吗?在两台不同的 Linux 机器上,似乎两个 Instants 都指的是自 POSIX 纪元以来的秒数。我的猜测是 Instants 确实有一个有效的开始时间,但那个开始时间是 implementation/device 依赖的。

# machine1
say(now * (1/3600) * (1/24) * (1/365.25)); # years from zero point
46.0748226200715

# machine2
say(now * (1/3600) * (1/24) * (1/365.25)); # years from zero point
46.0748712024946

无论如何,我的问题是,是否可以依赖 Instants 在不同进程之间保持一致,还是仅供 "Internal" 使用?

say (now).WHAT; # «(Instant)␤»
say (now * 1).WHAT # «(Num)␤»

任何数值运算符都会将其操作数强制转换为 Nums。如果您想要正确的字符串表示形式,请使用 .perl .

say (now).perl # «Instant.from-posix((<1211194481492/833>, 0))␤»

无论您在什么平台上,Instant.from-posix 总是相对于 Unix 纪元。

参见:https://github.com/rakudo/rakudo/blob/nom/src/core/Instant.pm#L15

当前在特定机器上的所有 Instant 对象都是可比较的,来自不同机器的 Instant 可能不是。

出于实用目的,在 POSIX 机器上,它目前根据 International Atomic Time (TAI), which is currently 36 seconds ahead of Coordinated Universal Time (UTC).
自 1970 年 1 月 1 日以来的秒数 (即使您知道您的代码只会在 POSIX 机器上 运行,也不应依赖于此)

在另一个系统上,基于机器开启后的时间长度可能更有意义。
因此在重启后,重启前的任何 Instants 将无法与重启后的 Instants 相比较。

如果要比较来自不同机器的 Instants,或将它们存储起来以备后用,请将其转换为标准化值。


您可以使用多种内置转换器

# runtime constant-like term
my \init = INIT now;

say init.to-posix.perl;
# (1454172565.36938, Bool::False)

say init.DateTime.Str;     # now.DateTime =~= DateTime.now
# 2016-01-30T16:49:25.369380Z

say init.Date.Str;         # now.Date =~= Date.today
# 2016-01-30

say init.DateTime.yyyy-mm-dd eq init.Date.Str;
# True

如果您需要的不仅仅是上面显示的内容,我建议只使用 DateTime 对象,因为它有各种有用的方法。

my $now = DateTime.now;
say $now.Str;
# 2016-01-30T11:29:14.928520-06:00

say $now.truncated-to('day').utc.Str;
# 2016-01-30T06:00:00Z
#             ^

say $now.utc.truncated-to('day').Str;
# 2016-01-30T00:00:00Z
#             ^

Date.todayDateTime.now 会考虑您当地的时区信息,而 now.Datenow.DateTime 则不能。


如果你真的只想处理 POSIX 次你可以使用 time ,它与 now.to-posix[0].Int.

大致相同