Christopher Bottoms
Christopher Bottoms

Reputation: 11168

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

This is a case where I can find the definition, but I don't quite grasp it. From the 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.

I don't understand how you can specify a particular moment in time without having an epoch? Doesn't it have a reference point? On two different Linux machines it seemed that both Instants referred to seconds since the POSIX Epoch. My guess is that Instants do have an effective start time, but that that start time is implementation/device dependent.

# 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

Anyway, so my question is, can Instants be relied upon to be consistent between different processes or are they for "Internal" use only?

Upvotes: 4

Views: 104

Answers (2)

Brad Gilbert
Brad Gilbert

Reputation: 34130

All Instant objects currently on a particular machine are comparable, Instants from different machines may not be.

For practical purposes, on POSIX machines it is currently based on the number of seconds since January 1st, 1970 according to International Atomic Time (TAI), which is currently 36 seconds ahead of Coordinated Universal Time (UTC).
(This should not be relied upon even if you know your code will only ever be run on a POSIX machine)

On another system it may make more sense for it to be based on the amount of time since the machine was turned on.
So after a reboot, any Instants from before the reboot will not be comparable to any after it.

If you want to compare the Instants from different machines, or store them for later use, convert it to a standardized value.


There are several built-in converters you can use

# 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

I would recommend just using DateTime objects if you need more than what is shown above, as it has various useful methods.

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.today and DateTime.now take into consideration your local timezone information, where as now.Date and now.DateTime can't.


If you really only want to deal with POSIX times you can use time which is roughly the same as now.to-posix[0].Int.

Upvotes: 3

user5854207
user5854207

Reputation:

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

Any numerical operator will coerce it's operands into Nums. If you want a proper string representation use .perl .

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

No matter what platform you are on, Instant.from-posix will always be relative to the Unix epoch.

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

Upvotes: 5

Related Questions