line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
package DateTimeX::Lite; |
3
|
18
|
|
|
18
|
|
114
|
use strict; |
|
18
|
|
|
|
|
40
|
|
|
18
|
|
|
|
|
861
|
|
4
|
18
|
|
|
18
|
|
109
|
use warnings; |
|
18
|
|
|
|
|
46
|
|
|
18
|
|
|
|
|
746
|
|
5
|
18
|
|
|
18
|
|
134
|
use Carp (); |
|
18
|
|
|
|
|
51
|
|
|
18
|
|
|
|
|
519
|
|
6
|
18
|
|
|
18
|
|
120
|
use Scalar::Util qw(blessed); |
|
18
|
|
|
|
|
43
|
|
|
18
|
|
|
|
|
1694
|
|
7
|
18
|
|
|
|
|
268
|
use overload ( 'fallback' => 1, |
8
|
|
|
|
|
|
|
'-' => '_subtract_overload', |
9
|
|
|
|
|
|
|
'+' => '_add_overload', |
10
|
18
|
|
|
18
|
|
212
|
); |
|
18
|
|
|
|
|
53
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
sub subtract_datetime |
14
|
|
|
|
|
|
|
{ |
15
|
51
|
|
|
51
|
0
|
5527
|
my $dt1 = shift; |
16
|
51
|
|
|
|
|
87
|
my $dt2 = shift; |
17
|
|
|
|
|
|
|
|
18
|
51
|
100
|
|
|
|
198
|
$dt2 = $dt2->clone->set_time_zone( $dt1->time_zone ) |
19
|
|
|
|
|
|
|
unless $dt1->time_zone->name eq $dt2->time_zone->name; |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# We only want a negative duration if $dt2 > $dt1 ($self) |
22
|
51
|
100
|
|
|
|
312
|
my ( $bigger, $smaller, $negative ) = |
23
|
|
|
|
|
|
|
( $dt1 >= $dt2 ? |
24
|
|
|
|
|
|
|
( $dt1, $dt2, 0 ) : |
25
|
|
|
|
|
|
|
( $dt2, $dt1, 1 ) |
26
|
|
|
|
|
|
|
); |
27
|
|
|
|
|
|
|
|
28
|
51
|
|
66
|
|
|
162
|
my $is_floating = $dt1->time_zone->is_floating && |
29
|
|
|
|
|
|
|
$dt2->time_zone->is_floating; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
|
32
|
51
|
|
|
|
|
114
|
my $minute_length = 60; |
33
|
51
|
100
|
|
|
|
125
|
unless ($is_floating) |
34
|
|
|
|
|
|
|
{ |
35
|
39
|
|
|
|
|
115
|
my ( $utc_rd_days, $utc_rd_secs ) = $smaller->utc_rd_values; |
36
|
|
|
|
|
|
|
|
37
|
39
|
100
|
66
|
|
|
174
|
if ( $utc_rd_secs >= 86340 && ! $is_floating ) |
38
|
|
|
|
|
|
|
{ |
39
|
|
|
|
|
|
|
# If the smaller of the two datetimes occurs in the last |
40
|
|
|
|
|
|
|
# UTC minute of the UTC day, then that minute may not be |
41
|
|
|
|
|
|
|
# 60 seconds long. If we need to subtract a minute from |
42
|
|
|
|
|
|
|
# the larger datetime's minutes count in order to adjust |
43
|
|
|
|
|
|
|
# the seconds difference to be positive, we need to know |
44
|
|
|
|
|
|
|
# how long that minute was. If one of the datetimes is |
45
|
|
|
|
|
|
|
# floating, we just assume a minute is 60 seconds. |
46
|
|
|
|
|
|
|
|
47
|
5
|
|
|
|
|
27
|
$minute_length = DateTimeX::Lite::LeapSecond::day_length($utc_rd_days) - 86340; |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
# This is a gross hack that basically figures out if the bigger of |
52
|
|
|
|
|
|
|
# the two datetimes is the day of a DST change. If it's a 23 hour |
53
|
|
|
|
|
|
|
# day (switching _to_ DST) then we subtract 60 minutes from the |
54
|
|
|
|
|
|
|
# local time. If it's a 25 hour day then we add 60 minutes to the |
55
|
|
|
|
|
|
|
# local time. |
56
|
|
|
|
|
|
|
# |
57
|
|
|
|
|
|
|
# This produces the most "intuitive" results, though there are |
58
|
|
|
|
|
|
|
# still reversibility problems with the resultant duration. |
59
|
|
|
|
|
|
|
# |
60
|
|
|
|
|
|
|
# However, if the two objects are on the same (local) date, and we |
61
|
|
|
|
|
|
|
# are not crossing a DST change, we don't want to invoke the hack |
62
|
|
|
|
|
|
|
# - see 38local-subtract.t |
63
|
51
|
|
|
|
|
197
|
my $bigger_min = $bigger->hour * 60 + $bigger->minute; |
64
|
51
|
100
|
100
|
|
|
183
|
if ( $bigger->time_zone->has_dst_changes |
|
|
|
66
|
|
|
|
|
65
|
|
|
|
|
|
|
&& ( $bigger->ymd ne $smaller->ymd |
66
|
|
|
|
|
|
|
|| $bigger->is_dst != $smaller->is_dst ) |
67
|
|
|
|
|
|
|
) |
68
|
|
|
|
|
|
|
{ |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
$bigger_min -= 60 |
71
|
|
|
|
|
|
|
# it's a 23 hour (local) day |
72
|
|
|
|
|
|
|
if ( $bigger->is_dst |
73
|
|
|
|
|
|
|
&& |
74
|
13
|
100
|
66
|
|
|
47
|
do { local $@; |
|
7
|
|
|
|
|
13
|
|
75
|
7
|
|
|
|
|
13
|
my $prev_day = eval { $bigger->clone->subtract( days => 1 ) }; |
|
7
|
|
|
|
|
29
|
|
76
|
7
|
100
|
100
|
|
|
62
|
$prev_day && ! $prev_day->is_dst ? 1 : 0 } |
77
|
|
|
|
|
|
|
); |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
$bigger_min += 60 |
80
|
|
|
|
|
|
|
# it's a 25 hour (local) day |
81
|
|
|
|
|
|
|
if ( ! $bigger->is_dst |
82
|
|
|
|
|
|
|
&& |
83
|
13
|
100
|
66
|
|
|
50
|
do { local $@; |
|
6
|
|
|
|
|
11
|
|
84
|
6
|
|
|
|
|
12
|
my $prev_day = eval { $bigger->clone->subtract( days => 1 ) }; |
|
6
|
|
|
|
|
27
|
|
85
|
6
|
100
|
66
|
|
|
59
|
$prev_day && $prev_day->is_dst ? 1 : 0 } |
86
|
|
|
|
|
|
|
); |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
|
89
|
51
|
|
|
|
|
235
|
my ( $months, $days, $minutes, $seconds, $nanoseconds ) = |
90
|
|
|
|
|
|
|
$dt1->_adjust_for_positive_difference |
91
|
|
|
|
|
|
|
( $bigger->year * 12 + $bigger->month, $smaller->year * 12 + $smaller->month, |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
$bigger->day, $smaller->day, |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
$bigger_min, $smaller->hour * 60 + $smaller->minute, |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
$bigger->second, $smaller->second, |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
$bigger->nanosecond, $smaller->nanosecond, |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
$minute_length, |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
# XXX - using the smaller as the month length is |
104
|
|
|
|
|
|
|
# somewhat arbitrary, we could also use the bigger - |
105
|
|
|
|
|
|
|
# either way we have reversibility problems |
106
|
|
|
|
|
|
|
DateTimeX::Lite::Util::month_length( $smaller->year, $smaller->month ), |
107
|
|
|
|
|
|
|
); |
108
|
|
|
|
|
|
|
|
109
|
51
|
100
|
|
|
|
179
|
if ($negative) |
110
|
|
|
|
|
|
|
{ |
111
|
16
|
|
|
|
|
46
|
for ( $months, $days, $minutes, $seconds, $nanoseconds ) |
112
|
|
|
|
|
|
|
{ |
113
|
|
|
|
|
|
|
# Some versions of Perl can end up with -0 if we do "0 * -1"!! |
114
|
80
|
100
|
|
|
|
231
|
$_ *= -1 if $_; |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
} |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
return |
119
|
51
|
|
|
|
|
288
|
DateTimeX::Lite::Duration->new |
120
|
|
|
|
|
|
|
( months => $months, |
121
|
|
|
|
|
|
|
days => $days, |
122
|
|
|
|
|
|
|
minutes => $minutes, |
123
|
|
|
|
|
|
|
seconds => $seconds, |
124
|
|
|
|
|
|
|
nanoseconds => $nanoseconds, |
125
|
|
|
|
|
|
|
); |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
sub _adjust_for_positive_difference |
129
|
|
|
|
|
|
|
{ |
130
|
55
|
|
|
55
|
|
160
|
my ( $self, |
131
|
|
|
|
|
|
|
$month1, $month2, |
132
|
|
|
|
|
|
|
$day1, $day2, |
133
|
|
|
|
|
|
|
$min1, $min2, |
134
|
|
|
|
|
|
|
$sec1, $sec2, |
135
|
|
|
|
|
|
|
$nano1, $nano2, |
136
|
|
|
|
|
|
|
$minute_length, |
137
|
|
|
|
|
|
|
$month_length, |
138
|
|
|
|
|
|
|
) = @_; |
139
|
|
|
|
|
|
|
|
140
|
55
|
100
|
|
|
|
154
|
if ( $nano1 < $nano2 ) |
141
|
|
|
|
|
|
|
{ |
142
|
7
|
|
|
|
|
13
|
$sec1--; |
143
|
7
|
|
|
|
|
29
|
$nano1 += &DateTimeX::Lite::MAX_NANOSECONDS; |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
|
146
|
55
|
100
|
|
|
|
148
|
if ( $sec1 < $sec2 ) |
147
|
|
|
|
|
|
|
{ |
148
|
8
|
|
|
|
|
10
|
$min1--; |
149
|
8
|
|
|
|
|
12
|
$sec1 += $minute_length; |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
# A day always has 24 * 60 minutes, though the minutes may vary in |
153
|
|
|
|
|
|
|
# length. |
154
|
55
|
100
|
|
|
|
140
|
if ( $min1 < $min2 ) |
155
|
|
|
|
|
|
|
{ |
156
|
8
|
|
|
|
|
13
|
$day1--; |
157
|
8
|
|
|
|
|
16
|
$min1 += 24 * 60; |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
|
160
|
55
|
100
|
|
|
|
153
|
if ( $day1 < $day2 ) |
161
|
|
|
|
|
|
|
{ |
162
|
12
|
|
|
|
|
15
|
$month1--; |
163
|
12
|
|
|
|
|
32
|
$day1 += $month_length; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
55
|
|
|
|
|
223
|
return ( $month1 - $month2, |
167
|
|
|
|
|
|
|
$day1 - $day2, |
168
|
|
|
|
|
|
|
$min1 - $min2, |
169
|
|
|
|
|
|
|
$sec1 - $sec2, |
170
|
|
|
|
|
|
|
$nano1 - $nano2, |
171
|
|
|
|
|
|
|
); |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
sub subtract_datetime_absolute |
175
|
|
|
|
|
|
|
{ |
176
|
8
|
|
|
8
|
0
|
48
|
my $self = shift; |
177
|
8
|
|
|
|
|
15
|
my $dt = shift; |
178
|
|
|
|
|
|
|
|
179
|
8
|
|
|
|
|
35
|
my $utc_rd_secs1 = $self->utc_rd_as_seconds; |
180
|
8
|
100
|
|
|
|
30
|
$utc_rd_secs1 += DateTimeX::Lite::LeapSecond::leap_seconds( $self->{utc_rd_days} ) |
181
|
|
|
|
|
|
|
if ! $self->time_zone->is_floating; |
182
|
|
|
|
|
|
|
|
183
|
8
|
|
|
|
|
33
|
my $utc_rd_secs2 = $dt->utc_rd_as_seconds; |
184
|
8
|
100
|
|
|
|
27
|
$utc_rd_secs2 += DateTimeX::Lite::LeapSecond::leap_seconds( $dt->{utc_rd_days} ) |
185
|
|
|
|
|
|
|
if ! $dt->time_zone->is_floating; |
186
|
|
|
|
|
|
|
|
187
|
8
|
|
|
|
|
18
|
my $seconds = $utc_rd_secs1 - $utc_rd_secs2; |
188
|
8
|
|
|
|
|
29
|
my $nanoseconds = $self->nanosecond - $dt->nanosecond; |
189
|
|
|
|
|
|
|
|
190
|
8
|
100
|
|
|
|
31
|
if ( $nanoseconds < 0 ) |
191
|
|
|
|
|
|
|
{ |
192
|
1
|
|
|
|
|
2
|
$seconds--; |
193
|
1
|
|
|
|
|
4
|
$nanoseconds += &DateTimeX::Lite::MAX_NANOSECONDS; |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
return |
197
|
8
|
|
|
|
|
40
|
DateTimeX::Lite::Duration->new |
198
|
|
|
|
|
|
|
( seconds => $seconds, |
199
|
|
|
|
|
|
|
nanoseconds => $nanoseconds, |
200
|
|
|
|
|
|
|
); |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
sub delta_md |
204
|
|
|
|
|
|
|
{ |
205
|
4
|
|
|
4
|
0
|
3445
|
my $self = shift; |
206
|
4
|
|
|
|
|
9
|
my $dt = shift; |
207
|
|
|
|
|
|
|
|
208
|
4
|
|
|
|
|
37
|
my ( $smaller, $bigger ) = sort $self, $dt; |
209
|
|
|
|
|
|
|
|
210
|
4
|
|
|
|
|
23
|
my ( $months, $days, undef, undef, undef ) = |
211
|
|
|
|
|
|
|
$dt->_adjust_for_positive_difference |
212
|
|
|
|
|
|
|
( $bigger->year * 12 + $bigger->month, $smaller->year * 12 + $smaller->month, |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
$bigger->day, $smaller->day, |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
0, 0, |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
0, 0, |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
0, 0, |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
60, |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
DateTimeX::Lite::Util::month_length( $smaller->year, $smaller->month ), |
225
|
|
|
|
|
|
|
); |
226
|
|
|
|
|
|
|
|
227
|
4
|
|
|
|
|
33
|
return DateTimeX::Lite::Duration->new( months => $months, |
228
|
|
|
|
|
|
|
days => $days ); |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
sub delta_days |
232
|
|
|
|
|
|
|
{ |
233
|
5
|
|
|
5
|
0
|
2435
|
my $self = shift; |
234
|
5
|
|
|
|
|
14
|
my $dt = shift; |
235
|
|
|
|
|
|
|
|
236
|
5
|
|
|
|
|
33
|
my ( $smaller, $bigger ) = sort( ($self->local_rd_values)[0], ($dt->local_rd_values)[0] ); |
237
|
|
|
|
|
|
|
|
238
|
5
|
|
|
|
|
39
|
DateTimeX::Lite::Duration->new( days => $bigger - $smaller ); |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
sub delta_ms |
242
|
|
|
|
|
|
|
{ |
243
|
3
|
|
|
3
|
0
|
11
|
my $self = shift; |
244
|
3
|
|
|
|
|
6
|
my $dt = shift; |
245
|
|
|
|
|
|
|
|
246
|
3
|
|
|
|
|
27
|
my ( $smaller, $greater ) = sort $self, $dt; |
247
|
|
|
|
|
|
|
|
248
|
3
|
|
|
|
|
13
|
my $days = int( $greater->jd - $smaller->jd ); |
249
|
|
|
|
|
|
|
|
250
|
3
|
|
|
|
|
16
|
my $dur = $greater->subtract_datetime($smaller); |
251
|
|
|
|
|
|
|
|
252
|
3
|
|
|
|
|
8
|
my %p; |
253
|
3
|
|
|
|
|
11
|
$p{hours} = $dur->hours + ( $days * 24 ); |
254
|
3
|
|
|
|
|
12
|
$p{minutes} = $dur->minutes; |
255
|
3
|
|
|
|
|
12
|
$p{seconds} = $dur->seconds; |
256
|
|
|
|
|
|
|
|
257
|
3
|
|
|
|
|
13
|
return DateTimeX::Lite::Duration->new(%p); |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
sub _add_overload |
261
|
|
|
|
|
|
|
{ |
262
|
4358
|
|
|
4358
|
|
8246
|
my ( $dt, $dur, $reversed ) = @_; |
263
|
|
|
|
|
|
|
|
264
|
4358
|
50
|
|
|
|
9867
|
if ($reversed) |
265
|
|
|
|
|
|
|
{ |
266
|
0
|
|
|
|
|
0
|
( $dur, $dt ) = ( $dt, $dur ); |
267
|
|
|
|
|
|
|
} |
268
|
|
|
|
|
|
|
|
269
|
4358
|
100
|
100
|
|
|
36549
|
unless ( blessed $dur && $dur->isa( 'DateTimeX::Lite::Duration' ) ) |
270
|
|
|
|
|
|
|
{ |
271
|
2
|
|
|
|
|
3
|
my $class = ref $dt; |
272
|
2
|
|
|
|
|
8
|
my $dt_string = overload::StrVal($dt); |
273
|
|
|
|
|
|
|
|
274
|
2
|
|
|
|
|
297
|
Carp::croak( "Cannot add $dur to a $class object ($dt_string).\n" |
275
|
|
|
|
|
|
|
. " Only a DateTimeX::Lite::Duration object can " |
276
|
|
|
|
|
|
|
. " be added to a $class object." ); |
277
|
|
|
|
|
|
|
} |
278
|
|
|
|
|
|
|
|
279
|
4356
|
|
|
|
|
15007
|
return $dt->clone->add_duration($dur); |
280
|
|
|
|
|
|
|
} |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
sub _subtract_overload |
283
|
|
|
|
|
|
|
{ |
284
|
1229
|
|
|
1229
|
|
3829
|
my ( $date1, $date2, $reversed ) = @_; |
285
|
|
|
|
|
|
|
|
286
|
1229
|
50
|
|
|
|
2732
|
if ($reversed) |
287
|
|
|
|
|
|
|
{ |
288
|
0
|
|
|
|
|
0
|
( $date2, $date1 ) = ( $date1, $date2 ); |
289
|
|
|
|
|
|
|
} |
290
|
|
|
|
|
|
|
|
291
|
1229
|
100
|
100
|
|
|
11576
|
if ( blessed $date2 && $date2->isa( 'DateTimeX::Lite::Duration' ) ) |
|
|
100
|
100
|
|
|
|
|
292
|
|
|
|
|
|
|
{ |
293
|
1208
|
|
|
|
|
4656
|
my $new = $date1->clone; |
294
|
1208
|
|
|
|
|
6794
|
$new->add_duration( $date2->inverse ); |
295
|
1208
|
|
|
|
|
11503
|
return $new; |
296
|
|
|
|
|
|
|
} |
297
|
|
|
|
|
|
|
elsif ( blessed $date2 && $date2->isa( 'DateTimeX::Lite' ) ) |
298
|
|
|
|
|
|
|
{ |
299
|
19
|
|
|
|
|
71
|
return $date1->subtract_datetime($date2); |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
else |
302
|
|
|
|
|
|
|
{ |
303
|
2
|
|
|
|
|
5
|
my $class = ref $date1; |
304
|
2
|
|
|
|
|
6
|
my $dt_string = overload::StrVal($date1); |
305
|
|
|
|
|
|
|
|
306
|
2
|
|
|
|
|
275
|
Carp::croak( "Cannot subtract $date2 from a $class object ($dt_string).\n" |
307
|
|
|
|
|
|
|
. " Only a DateTimeX::Lite::Duration or DateTimeX::Lite object can " |
308
|
|
|
|
|
|
|
. " be subtracted from a $class object." ); |
309
|
|
|
|
|
|
|
} |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
|
312
|
620
|
|
|
620
|
0
|
7721
|
sub add { return shift->add_duration( DateTimeX::Lite::Duration->new(@_) ) } |
313
|
|
|
|
|
|
|
|
314
|
54
|
|
|
54
|
0
|
387
|
sub subtract { return shift->subtract_duration( DateTimeX::Lite::Duration->new(@_) ) } |
315
|
|
|
|
|
|
|
|
316
|
71
|
|
|
71
|
0
|
367
|
sub subtract_duration { return $_[0]->add_duration( $_[1]->inverse ) } |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
sub add_duration |
319
|
|
|
|
|
|
|
{ |
320
|
6324
|
|
|
6324
|
0
|
10233
|
my ($self, $dur) = @_; |
321
|
6324
|
50
|
33
|
|
|
42972
|
if (! blessed $dur || !$dur->isa('DateTimeX::Lite::Duration')) { |
322
|
0
|
|
|
|
|
0
|
Carp::croak("Duration is not a DateTimeX::Lite::Duration object"); |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
# simple optimization |
326
|
6324
|
50
|
|
|
|
23692
|
return $self if $dur->is_zero; |
327
|
|
|
|
|
|
|
|
328
|
6324
|
|
|
|
|
23986
|
my %deltas = $dur->deltas; |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
# This bit isn't quite right since DateTimeX::Lite::Infinite::Future - |
331
|
|
|
|
|
|
|
# infinite duration should NaN |
332
|
6324
|
|
|
|
|
20519
|
foreach my $val ( values %deltas ) |
333
|
|
|
|
|
|
|
{ |
334
|
31612
|
|
|
|
|
31528
|
my $inf; |
335
|
31612
|
100
|
|
|
|
142024
|
if ( $val == &DateTimeX::Lite::INFINITY ) |
|
|
100
|
|
|
|
|
|
336
|
|
|
|
|
|
|
{ |
337
|
1
|
|
|
|
|
9
|
$inf = DateTimeX::Lite::Infinite::Future->new; |
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
elsif ( $val == &DateTimeX::Lite::NEG_INFINITY ) |
340
|
|
|
|
|
|
|
{ |
341
|
1
|
|
|
|
|
9
|
$inf = DateTimeX::Lite::Infinite::Past->new; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
|
344
|
31612
|
100
|
|
|
|
76475
|
if ($inf) |
345
|
|
|
|
|
|
|
{ |
346
|
2
|
|
|
|
|
25
|
%$self = %$inf; |
347
|
2
|
|
|
|
|
14
|
bless $self, blessed $inf; |
348
|
|
|
|
|
|
|
|
349
|
2
|
|
|
|
|
11
|
return $self; |
350
|
|
|
|
|
|
|
} |
351
|
|
|
|
|
|
|
} |
352
|
|
|
|
|
|
|
|
353
|
6322
|
100
|
|
|
|
22679
|
return $self if $self->is_infinite; |
354
|
|
|
|
|
|
|
|
355
|
6318
|
100
|
|
|
|
16608
|
if ( $deltas{days} ) |
356
|
|
|
|
|
|
|
{ |
357
|
3483
|
|
|
|
|
7121
|
$self->{local_rd_days} += $deltas{days}; |
358
|
|
|
|
|
|
|
|
359
|
3483
|
|
|
|
|
8729
|
$self->{utc_year} += int( $deltas{days} / 365 ) + 1; |
360
|
|
|
|
|
|
|
} |
361
|
|
|
|
|
|
|
|
362
|
6318
|
100
|
|
|
|
14632
|
if ( $deltas{months} ) |
363
|
|
|
|
|
|
|
{ |
364
|
|
|
|
|
|
|
# For preserve mode, if it is the last day of the month, make |
365
|
|
|
|
|
|
|
# it the 0th day of the following month (which then will |
366
|
|
|
|
|
|
|
# normalize back to the last day of the new month). |
367
|
575
|
100
|
|
|
|
2323
|
my ($y, $m, $d) = ( $dur->is_preserve_mode ? |
368
|
|
|
|
|
|
|
DateTimeX::Lite::Util::rd2ymd( $self->{local_rd_days} + 1 ) : |
369
|
|
|
|
|
|
|
DateTimeX::Lite::Util::rd2ymd( $self->{local_rd_days} ) |
370
|
|
|
|
|
|
|
); |
371
|
|
|
|
|
|
|
|
372
|
575
|
100
|
|
|
|
1950
|
$d -= 1 if $dur->is_preserve_mode; |
373
|
|
|
|
|
|
|
|
374
|
575
|
100
|
100
|
|
|
2223
|
if ( ! $dur->is_wrap_mode && $d > 28 ) |
375
|
|
|
|
|
|
|
{ |
376
|
|
|
|
|
|
|
# find the rd for the last day of our target month |
377
|
1
|
|
|
|
|
7
|
$self->{local_rd_days} = DateTimeX::Lite::Util::ymd2rd( $y, $m + $deltas{months} + 1, 0 ); |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
# what day of the month is it? (discard year and month) |
380
|
1
|
|
|
|
|
6
|
my $last_day = (DateTimeX::Lite::Util::rd2ymd( $self->{local_rd_days} ))[2]; |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
# if our original day was less than the last day, |
383
|
|
|
|
|
|
|
# use that instead |
384
|
1
|
50
|
|
|
|
6
|
$self->{local_rd_days} -= $last_day - $d if $last_day > $d; |
385
|
|
|
|
|
|
|
} |
386
|
|
|
|
|
|
|
else |
387
|
|
|
|
|
|
|
{ |
388
|
574
|
|
|
|
|
3824
|
$self->{local_rd_days} = DateTimeX::Lite::Util::ymd2rd( $y, $m + $deltas{months}, $d ); |
389
|
|
|
|
|
|
|
} |
390
|
|
|
|
|
|
|
|
391
|
575
|
|
|
|
|
2136
|
$self->{utc_year} += int( $deltas{months} / 12 ) + 1; |
392
|
|
|
|
|
|
|
} |
393
|
|
|
|
|
|
|
|
394
|
6318
|
100
|
100
|
|
|
23617
|
if ( $deltas{days} || $deltas{months} ) |
395
|
|
|
|
|
|
|
{ |
396
|
4056
|
|
|
|
|
12009
|
$self->_calc_utc_rd; |
397
|
|
|
|
|
|
|
|
398
|
4053
|
|
|
|
|
12701
|
$self->_handle_offset_modifier( $self->second ); |
399
|
|
|
|
|
|
|
} |
400
|
|
|
|
|
|
|
|
401
|
6315
|
100
|
|
|
|
20426
|
if ( $deltas{minutes} ) |
402
|
|
|
|
|
|
|
{ |
403
|
85
|
|
|
|
|
220
|
$self->{utc_rd_secs} += $deltas{minutes} * 60; |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
# This intentionally ignores leap seconds |
406
|
85
|
|
|
|
|
332
|
DateTimeX::Lite::Util::normalize_tai_seconds( $self->{utc_rd_days}, $self->{utc_rd_secs} ); |
407
|
|
|
|
|
|
|
} |
408
|
|
|
|
|
|
|
|
409
|
6315
|
100
|
100
|
|
|
25386
|
if ( $deltas{seconds} || $deltas{nanoseconds} ) |
410
|
|
|
|
|
|
|
{ |
411
|
2200
|
|
|
|
|
4418
|
$self->{utc_rd_secs} += $deltas{seconds}; |
412
|
|
|
|
|
|
|
|
413
|
2200
|
100
|
|
|
|
5385
|
if ( $deltas{nanoseconds} ) |
414
|
|
|
|
|
|
|
{ |
415
|
3
|
|
|
|
|
9
|
$self->{rd_nanosecs} += $deltas{nanoseconds}; |
416
|
3
|
|
|
|
|
15
|
DateTimeX::Lite::Util::normalize_nanoseconds( $self->{utc_rd_secs}, $self->{rd_nanosecs} ); |
417
|
|
|
|
|
|
|
} |
418
|
|
|
|
|
|
|
|
419
|
2200
|
|
|
|
|
7517
|
DateTimeX::Lite::Util::normalize_seconds($self); |
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
# This might be some big number much bigger than 60, but |
422
|
|
|
|
|
|
|
# that's ok (there are tests in 19leap_second.t to confirm |
423
|
|
|
|
|
|
|
# that) |
424
|
2200
|
|
|
|
|
7213
|
$self->_handle_offset_modifier( $self->second + $deltas{seconds} ); |
425
|
|
|
|
|
|
|
} |
426
|
|
|
|
|
|
|
|
427
|
6315
|
50
|
|
|
|
37049
|
my $new = |
428
|
|
|
|
|
|
|
(ref $self)->from_object |
429
|
|
|
|
|
|
|
( object => $self, |
430
|
|
|
|
|
|
|
locale => $self->{locale}, |
431
|
|
|
|
|
|
|
( $self->{formatter} ? ( formatter => $self->{formatter} ) : () ), |
432
|
|
|
|
|
|
|
); |
433
|
|
|
|
|
|
|
|
434
|
6314
|
|
|
|
|
78765
|
%$self = %$new; |
435
|
|
|
|
|
|
|
|
436
|
6314
|
|
|
|
|
76319
|
return $self; |
437
|
|
|
|
|
|
|
} |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
1; |