-
Notifications
You must be signed in to change notification settings - Fork 135
/
DateTime-Instant-Duration.t
129 lines (100 loc) · 5.41 KB
/
DateTime-Instant-Duration.t
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
128
129
use v6;
use Test;
plan 33;
=begin pod
DateTime is the only means of constructing arbitrary Instants,
so we test some of the properties of Instants and Durations here
rather than in S02/instants-and-duration.t.
=end pod
sub dtp($year, $month, $day, $hour, $minute, $second) {
DateTime.new(:$year, :$month, :$day, :$hour, :$minute, :$second)
}
sub dtpi($year, $month, $day, $hour, $minute, $second) {
DateTime.new(:$year, :$month, :$day, :$hour, :$minute, :$second).Instant
}
sub dti(*%args) { DateTime.new(|{year => 1984, %args}).Instant }
sub dsi($s) { DateTime.new($s).Instant }
sub diff(%early?, *%late) { + do dti(|%late) - dti(|%early) }
sub days($n) { $n * 24 * 60 * 60 }
# L<S32::Temporal/Accessors/'the method Instant'>
isa_ok dti, Instant, 'DateTime.Instant returns an Instant';
is dti, dti, 'Equal DateTimes yield equal Instants';
is diff, 0, 'The difference of equal Instants is 0';
ok dsi('2005-12-31T23:59:60') < dsi('2006-01-01T00:00:00'), 'DateTime.Instant counts leap seconds';
# These seconds have equal POSIX times.
is diff(second => 5), 5, 'Instant subtraction (seconds)';
is diff(second => 2/7), 2/7, 'Instant subtraction (non-integral seconds)';
is diff(second => 3.14159), 3.14159, 'Instant subtraction (needing high precision)';
is diff(minute => 15), 15 * 60, 'Instant subtraction (minutes)';
is diff(:hour(3), :minute(15), :second(33)),
3*60*60 + 15*60 + 33, 'Instant subtraction (HMS)';
is diff(day => 4), days(3), 'Instant subtraction (days)';
is diff(month => 2), days(31), 'Instant subtraction (a month)';
is diff(month => 3), days(31 + 29), 'Instant subtraction (Jan and Feb, leap year)';
is diff({year => 1985}, year => 1985, month => 3), days(31 + 28), 'Instant subtraction (Jan and Feb, common year)';
is diff(:year(1985), :month(3), :day(14)),
days(366 + 31 + 28 + 13), 'Instant subtraction (YMD)';
is +(DateTime.new('1985-03-14T13:28:22').Instant - dti),
days(366 + 31 + 28 + 13) + 13*60*60 + 28*60 + 22, 'Instant subtraction (YMDHMS)';
{
my $a = dtp(2004, 12, 31, 23, 57, 8.5);
my $b = dtp(2005, 1, 1, 2, 22, 13.4);
my $expected-diff = 60 - 8.5 + 2*60 + 2*60*60 + 22*60 + 13.4;
is +($b.Instant() - $a.Instant), $expected-diff, 'Instant subtraction (ugly case)';
$a .= clone(timezone => 35*60 - 5);
$b .= clone(timezone => 3*60*60);
is +($a.Instant() - $b.Instant), 0.1, 'Instant subtraction (time zones)';
diff({:year(1997), :month(6), :day(30)},
:year(1997), :month(7), :day(1)),
days(1) + 1, 'Instant subtraction (June 30 leap second)';
$a .= clone(year => 2005, timezone => 0);
$b .= clone(year => 2006, timezone => 0);
is +($b.Instant() - $a.Instant), $expected-diff + 1, 'Instant subtraction (December 31 leap second)';
$a = DateTime.new('2006-01-01T12:33:58+1234');
# In UTC, $a is 2005-12-31T23:59:58.
$b = DateTime.new('2006-01-01T12:44:03+1244');
# In UTC, $b is 2006-01-01T00:00:03.
is +($b.Instant() - $a.Instant), 6, 'Instant subtraction (leap second and time zones)';
$a .= clone(year => 1973);
$b .= clone(year => 2008);
is +($b.Instant() - $a.Instant), 1_104_451_227, 'Instant subtraction (thirty-year span)';
# I got this figure by adding 22 (the number of leap seconds
# between the two moments) to the difference of POSIX
# times.
}
# L<S32::Temporal/C<DateTime>/DateTime.new(now)>
is ~DateTime.new(dsi('2004-03-05T12:43:22')), '2004-03-05T12:43:22Z', 'Round-tripping DateTime.Instant (2004-03-05T12:43:22Z)';
is ~DateTime.new(dsi('2005-12-31T23:59:59')), '2005-12-31T23:59:59Z', 'Round-tripping DateTime.Instant (2005-12-31T23:59:59Z)';
is ~DateTime.new(dsi('2005-12-31T23:59:60')), '2005-12-31T23:59:60Z', 'Round-tripping DateTime.Instant (2005-12-31T23:59:60Z)';
is ~DateTime.new(dsi('2006-01-01T00:00:00')), '2006-01-01T00:00:00Z', 'Round-tripping DateTime.Instant (2006-01-01T00:00:00Z)';
is DateTime.new(dtpi 2005, 12, 31, 23, 59, 59.5).second, 59.5, 'Round-tripping DateTime.Instant (2005-12-31T23:59:59.5Z)';
is DateTime.new(dtpi 2005, 12, 31, 23, 59, 60.5).second, 60.5, 'Round-tripping DateTime.Instant (2005-12-31T23:59:60.5Z)';
is DateTime.new(dtpi 2006, 1, 1, 0, 0, 0.5).second, 0.5, 'Round-tripping DateTime.Instant (2006-01-01T00:00:00.5Z)';
is DateTime.new(dtpi 2005, 12, 31, 23, 59, 59.2).second, 59.2, 'Round-tripping DateTime.Instant (2005-12-31T23:59:59.2Z)';
is DateTime.new(dtpi 2005, 12, 31, 23, 59, 60.2).second, 60.2, 'Round-tripping DateTime.Instant (2005-12-31T23:59:60.2Z)';
is DateTime.new(dtpi 2006, 1, 1, 0, 0, 0.2).second, 0.2, 'Round-tripping DateTime.Instant (2006-01-01T00:00:00.2Z)';
{
my $last-t = time;
my $t;
loop { # Loop until we reach the beginning of the next second.
$t = time;
last if $t > $last-t;
$last-t = $t;
}
my $i = now; # $t and $i are supposed to be within the
# same UTC second, but if we're unlucky they
# might not be.
is ~DateTime.new($i), ~DateTime.new($t), 'DateTime.new(now)';
}
{
my $dt = DateTime.new(dsi('1999-12-31T23:59:59'),
timezone => -(5*60*60 + 55*60),
formatter => { .day ~ '/' ~ .month ~ '/' ~ .year ~ ' ' ~
.second ~ 's' ~ .minute ~ 'm' ~ .hour ~ 'h' });
is ~$dt, '31/12/1999 59s4m18h', 'DateTime.new(Instant) with time zone and formatter';
}
{
my $i = dtpi 1988, 11, 22, 18, 42, 15.9;
is $i.perl.EVAL, $i, 'Round-tripping Instant.perl';
}
# vim: ft=perl6