/
Instant.pm
127 lines (108 loc) · 3.39 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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
my class Duration {... }
my class Instant is Cool does Real {
has Rat $.tai;
# A linear count of seconds since 1970-01-01T00:00:00Z, plus
# tai-utc::initial-offset. Thus, $.tai matches TAI from 1970
# to the present.
method new($tai) { self.bless: tai => $tai.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 = $posix.floor;
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 = $.tai.floor;
my $offset = tai-utc::initial-offset;
for tai-utc::leap-second-posix() {
if $_ < $n - $offset {
++$offset;
} else {
return ($.tai - $offset, $n - $offset == $_)
}
}
($.tai - $offset, False)
}
multi method Str(Instant:D:) {
'Instant:' ~ $.tai
}
multi method perl(Instant:D:) {
"Instant.new($.tai.perl())";
}
method Bridge(Instant:D:) { $.tai.Bridge }
method Num (Instant:D:) { $.tai.Num }
method Int (Instant:D:) { $.tai.Int }
method narrow(Instant:D:) { $.tai.narrow }
# TODO: should be the new .gist, probably
# method Str() {
# 'Instant:' ~ default-formatter
# ::DateTime.new(self), :subseconds
# }
}
multi sub infix:«cmp»(Instant:D $a, Instant:D $b) {
$a.tai <=> $b.tai }
multi sub infix:«<=>»(Instant:D $a, Instant:D $b) {
$a.tai <=> $b.tai
}
multi sub infix:«==»(Instant:D $a, Instant:D $b) {
$a.tai == $b.tai
}
multi sub infix:«!=»(Instant:D $a, Instant:D $b) {
$a.tai != $b.tai
}
multi sub infix:«<»(Instant:D $a, Instant:D $b) {
$a.tai < $b.tai
}
multi sub infix:«>»(Instant:D $a, Instant:D $b) {
$a.tai > $b.tai
}
multi sub infix:«<=»(Instant:D $a, Instant:D $b) {
$a.tai <= $b.tai
}
multi sub infix:«>=»(Instant:D $a, Instant:D $b) {
$a.tai >= $b.tai
}
multi sub infix:<+>(Instant:D $a, Real:D $b) {
Instant.new: $a.tai + $b;
}
multi sub infix:<+>(Real:D $a, Instant:D $b) {
Instant.new: $a + $b.tai;
}
multi sub infix:<+>(Instant:D $a, Duration:D $b) {
Instant.new: $a.tai + $b.tai;
}
multi sub infix:<+>(Duration:D $a, Instant:D $b) {
Instant.new: $a.tai + $b.tai;
}
multi sub infix:<->(Instant:D $a, Instant:D $b) {
Duration.new: $a.tai - $b.tai;
}
multi sub infix:<->(Instant:D $a, Real:D $b) {
Instant.new: $a.tai - $b;
}
sub term:<time>() { nqp::p6box_i(nqp::time_i()) }
sub term:<now>() {
# FIXME: During a leap second, the returned value is one
# second greater than it should be.
Instant.from-posix: nqp::time_n
}
#{
my num $init-time-num = nqp::time_n; # need find a way to not leak this
multi sub INITIALIZE_DYNAMIC('$*INITTIME') {
PROCESS::<$INITTIME> := Instant.from-posix: $init-time-num;
}
#}
# vim: ft=perl6 expandtab sw=4