/
Instant.pm
111 lines (94 loc) · 2.78 KB
/
Instant.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use v6;
class Instant does Real {
has Rat $.x;
# A linear count of seconds since 1970-01-01T00:00:00Z, plus
# tai-utc::initial-offset. Thus, $.x matches TAI from 1970
# to the present.
method new($x) { self.bless: *, x => $x.Rat }
method from-posix($posix, Bool $prefer-leap-second = False) {
# $posix is in general not expected to be an integer.
# If $prefer-leap-second is true, 915148800 is interpreted to
# mean 1998-12-31T23:59:60Z rather than 1999-01-01T00:00:00Z.
my $p = floor $posix;
my $offset = tai-utc::initial-offset;
for tai-utc::leap-second-posix() {
if $_ < $p {
++$offset;
} else {
return self.new: $posix + $offset + do
$_ == $p && !$prefer-leap-second
}
}
self.new: $posix + $offset;
}
method to-posix() {
# The inverse of .from-posix, except that the second return
# value is true if *and only if* this Instant is in a leap
# second.
my $n = floor $.x;
my $offset = tai-utc::initial-offset;
for tai-utc::leap-second-posix() {
if $_ < $n - $offset {
++$offset;
} else {
return ($.x - $offset, $n - $offset == $_)
}
}
($.x - $offset, False)
}
method Str() {
'Instant:' ~ default-formatter
::DateTime.new(self), :subseconds
}
method perl() {
sprintf '(DateTime.new(year => 1970).Instant + %s)',
($.x - tai-utc::initial-offset).perl
}
}
our multi sub infix:«cmp»(Instant $a, Instant $b) {
$a.x <=> $b.x
}
our multi sub infix:«<=>»(Instant $a, Instant $b) {
$a.x <=> $b.x
}
our multi sub infix:«==»(Instant $a, Instant $b) {
$a.x == $b.x
}
our multi sub infix:«!=»(Instant $a, Instant $b) {
$a.x != $b.x
}
our multi sub infix:«<»(Instant $a, Instant $b) {
$a.x < $b.x
}
our multi sub infix:«>»(Instant $a, Instant $b) {
$a.x > $b.x
}
our multi sub infix:«<=»(Instant $a, Instant $b) {
$a.x <= $b.x
}
our multi sub infix:«>=»(Instant $a, Instant $b) {
$a.x >= $b.x
}
our multi sub infix:<+>(Instant $a, Real $b) {
Instant.new: $a.x + $b;
}
our multi sub infix:<+>(Real $a, Instant $b) {
Instant.new: $a + $b.x;
}
our multi sub infix:<+>(Instant $a, Duration $b) {
Instant.new: $a.x + $b.x;
}
our multi sub infix:<+>(Duration $a, Instant $b) {
Instant.new: $a.x + $b.x;
}
our multi sub infix:<->(Instant $a, Instant $b) {
Duration.new: $a.x - $b.x;
}
our multi sub infix:<->(Instant $a, Real $b) {
Instant.new: $a.x - $b;
}
our sub term:<now>() {
# FIXME: During a leap second, the returned value is one
# second greater than it should be.
Instant.from-posix: pir::time__n
}