File Coverage

blib/lib/Time/C.pm
Criterion Covered Total %
statement 558 594 93.9
branch 279 428 65.1
condition 28 37 75.6
subroutine 65 65 100.0
pod 29 29 100.0
total 959 1153 83.1


line stmt bran cond sub pod time code
1 10     10   187896 use strict;
  10         28  
  10         275  
2 10     10   49 use warnings;
  10         20  
  10         811  
3             package Time::C;
4             $Time::C::VERSION = '0.024';
5             # ABSTRACT: Convenient time manipulation.
6              
7             use overload (
8 673     673   27081 '""' => sub { shift->string },
9 79     79   221 bool => sub { 1 },
10 10         98 fallback => 1,
11 10     10   8863 );
  10         8888  
12              
13 10     10   879 use Carp qw/ croak /;
  10         32  
  10         647  
14 10     10   4673 use Function::Parameters qw/ :strict /;
  10         28497  
  10         750  
15 10     10   7897 use Time::C::Sentinel;
  10         981  
  10         1146  
16 10     10   3099 use Time::D;
  10         28  
  10         294  
17 10     10   4399 use Time::P ();
  10         45  
  10         319  
18 10     10   4108 use Time::F ();
  10         37  
  10         294  
19 10     10   4353 use Time::Moment;
  10         10131  
  10         334  
20 10     10   5254 use Time::Zone::Olson;
  10         227244  
  10         3407  
21              
22              
23              
24 536 50   536 1 10933 method new ($c: $year =, $month =, $day =, $hour =, $minute =, $second =, $tz =) {
  536 50       1215  
  536         851  
  536         1248  
  536         761  
25 536         881 my $t;
26 536   100     5297 my %defineds = (
27             epoch_d => (defined($year) and defined($month) and defined($day) and defined($hour) and defined($minute) and defined($second)),
28             year => defined($year),
29             month => defined($month),
30             mday => defined($day),
31             week => 0,
32             wday => 0,
33             yday => 0,
34             hour => defined($hour),
35             minute => defined($minute),
36             second => defined($second),
37             tz_d => defined($tz),
38             offset => 0,
39             );
40              
41 536 100       1301 if (not defined $year) {
42 3         18 $t = $c->now_utc();
43 3         103 %$t = ( %$t, %defineds );
44 3         27 return $t;
45             }
46              
47 533   100     7175 my $tm = Time::Moment->new(year => $year, month => $month // 1, day => $day // 1, hour => $hour // 0, minute => $minute // 0, second => $second // 0, offset => 0);
      100        
      100        
      100        
      100        
48              
49 533 100       1427 if (not defined $tz) { $tz = 'UTC'; }
  498         825  
50              
51 533 100 66     1503 if ($tz ne 'UTC' and $tz ne 'GMT') {
52 10         65 my $offset = _get_offset($tm->epoch, $tz);
53 10         80 $tm = $tm->with_offset_same_local($offset);
54 10         79 $offset = _get_offset($tm->epoch, $tz);
55 10         64 $tm = $tm->with_offset_same_local($offset);
56             }
57              
58 533         1855 $t = $c->localtime($tm->epoch, $tz);
59 533         6281 %$t = (%$t, %defineds);
60 533         3256 return $t;
61             }
62              
63              
64 320 50 66 320 1 13833 method mktime ($c: :$epoch =, :$second =, :$minute =, :$hour =, :$mday =, :$month =, :$wday =, :$week =, :$yday =, :$year =, :$tz =, :$offset =) {
  320 50       1466  
  320 50       574  
  320         860  
  320         608  
  320         515  
  320         448  
  320         509  
  320         438  
  320         456  
  320         503  
  320         571  
  320         527  
  320         509  
  320         519  
  320         517  
  320         745  
  320         437  
65              
66             # Alright, time to try and construct a Time::C object with what we have
67             # We'll start with the easiest one: epoch
68             # Then go on to creating it from the date bits, and the time bits
69              
70 320         458 my $t;
71 320         1819 my %defineds = (
72             epoch_d => defined($epoch),
73             year => defined($year),
74             month => defined($month),
75             mday => defined($mday),
76             week => defined($week),
77             wday => defined($wday),
78             yday => defined($yday),
79             hour => defined($hour),
80             minute => defined($minute),
81             second => defined($second),
82             tz_d => defined($tz),
83             offset => defined($offset),
84             );
85              
86 320 100       834 if (defined $epoch) {
    100          
87 9         44 $t = Time::C->gmtime($epoch);
88              
89 9 100       41 if (defined $tz) {
    50          
90 7         30 $t->tz = $tz;
91             } elsif (defined $offset) {
92 2         11 $t->offset = $offset;
93             }
94              
95 9         91 $t->{tz_d} = $defineds{tz_d};
96              
97 9         81 return $t;
98             } elsif (defined $year) { # We have a year at least...
99 300 100       653 if (defined $month) {
    100          
    100          
100 14 100       38 if (defined $mday) {
101 9         43 $t = Time::C->new($year, $month, $mday);
102             } else {
103 5         13 $t = Time::C->new($year, $month);
104             }
105             } elsif (defined $week) {
106 277         656 $t = Time::C->new($year);
107 277         736 $t->day_of_week++ while ($t->week > 1);
108 277         1087 $t = $t->week($week)->day_of_week(1);
109              
110 277 100       648 if (defined $wday) { $t->day_of_week = $wday; }
  164         292  
111 113         215 else { $t->{wday} = 0; }
112             } elsif (defined $yday) {
113 3         9 $t = Time::C->new($year)->day_of_year($yday);
114             } else { # we have neither month, week, or day of year!
115 6         14 $t = Time::C->new($year);
116             }
117              
118             # Now add the time bits on top...
119 300 100       861 if (defined $hour) { $t->hour = $hour; }
  7         26  
120 300 100       780 if (defined $minute) { $t->minute = $minute; }
  7         25  
121 300 100       623 if (defined $second) { $t->second = $second; }
  7         30  
122             } else {
123             # If we don't have a year, let's use the current year
124 11         30 $year = Time::C->now($tz)->tz('UTC', 1)->year;
125 11 100       79 if (defined $month) {
    100          
    100          
126 1 50       4 if (defined $mday) {
127 0         0 $t = Time::C->new($year, $month, $mday);
128             } else {
129 1         4 $t = Time::C->new($year, $month);
130             }
131              
132             # Now add the time bits on top...
133 1 50       5 if (defined $hour) { $t->hour = $hour; }
  0         0  
134 1 50       4 if (defined $minute) { $t->minute = $minute; }
  0         0  
135 1 50       4 if (defined $second) { $t->second = $second; }
  0         0  
136             } elsif (defined $week) {
137 1         3 $t = Time::C->new($year);
138 1         5 $t->day_of_week++ while ($t->week > 1);
139 1         4 $t = $t->week($week)->day_of_week(1);
140              
141 1 50       4 if (defined $wday) { $t->day_of_week = $wday; }
  0         0  
142 1         3 else { $t->{wday} = 0; }
143              
144             # Now add the time bits on top...
145 1 50       4 if (defined $hour) { $t->hour = $hour; }
  0         0  
146 1 50       4 if (defined $minute) { $t->minute = $minute; }
  0         0  
147 1 50       3 if (defined $second) { $t->second = $second; }
  0         0  
148             } elsif (defined $yday) {
149 1         5 $t = Time::C->new($year)->day_of_year($yday);
150              
151             # Now add the time bits on top...
152 1 50       4 if (defined $hour) { $t->hour = $hour; }
  0         0  
153 1 50       3 if (defined $minute) { $t->minute = $minute; }
  0         0  
154 1 50       3 if (defined $second) { $t->second = $second; }
  0         0  
155             } else {
156             # We have neither year, month, week, or day of year ...
157             # So let's just make a time for today's date
158 8         24 $t = Time::C->now($tz)->second_of_day(0)->tz('UTC', 1);
159              
160             # Mark these as being undefined
161             $t->{epoch_d} = $t->{tz_d} = $t->{offset} = $t->{year} =
162             $t->{month} = $t->{mday} = $t->{week} = $t->{wday} = $t->{yday} =
163 8         41 $t->{hour} = $t->{minute} = $t->{second} = 0;
164              
165 8 100 66     440 croak "Could not mktime: No date specified and no time given."
      66        
166             if not defined $hour and not defined $minute and not defined $second;
167              
168             # And add the time bits on top...
169             # - if hour not defined, use current hour
170             # - if hour and minute not defined, use current minute
171 5 100       15 if (defined $hour) { $t->hour = $hour; } else { $t->hour = Time::C->now($tz)->tz('UTC', 1)->hour; }
  2         5  
  3         10  
172 5 100       35 if (defined $minute) { $t->minute = $minute; } elsif (not defined $hour) { $t->second_of_day = Time::C->now($tz)->tz('UTC', 1)->second(0)->second_of_day; }
  2 100       8  
  2         10  
173 5 100       28 if (defined $second) { $t->second = $second; }
  3         8  
174             }
175 8         20 $t->{year} = 0;
176             }
177              
178             # And last, adjust for timezone bits
179              
180 308 100       841 if (defined $tz) {
    50          
181 1         5 $t = $t->tz($tz, 1);
182             } elsif (defined $offset) {
183 0         0 $t->_tm = $t->tm->with_offset_same_local($offset);
184 0         0 $t->offset = $offset;
185             }
186              
187 308         1747 return $t;
188             }
189              
190              
191 671 50   671 1 2147 method localtime ($c: $epoch, $tz = $ENV{TZ}) {
  671 50       1508  
  671 100       1067  
  671         1897  
  671         934  
192 671         3179 my %defineds = (
193             epoch_d => 1,
194             year => 1,
195             month => 1,
196             mday => 1,
197             week => 1,
198             wday => 1,
199             yday => 1,
200             hour => 1,
201             minute => 1,
202             second => 1,
203             tz_d => defined($tz),
204             offset => 0,
205             );
206 671 100       1542 $tz = 'UTC' unless defined $tz;
207 671         1693 _verify_tz($tz);
208 671         7212 bless {epoch => $epoch, tz => $tz, %defineds}, $c;
209             }
210              
211              
212 103 50   103 1 682 method gmtime ($c: $epoch) { $c->localtime( $epoch, 'UTC' ); }
  103 50       253  
  103         185  
  103         310  
  103         177  
  103         297  
213              
214              
215 28 50   28 1 564 method now ($c: $tz = $ENV{TZ}) { $c->localtime( time, $tz ); }
  28 50       73  
  28 100       49  
  28         83  
  28         40  
  28         80  
216              
217              
218 6 50   6 1 861 method now_utc ($c:) { $c->localtime( time, 'UTC' ); }
  6 50       23  
  6         16  
  6         12  
  6         38  
219              
220              
221 10 50 66 10 1 154931 method from_string ($c: $str, :$format = undef, :$locale = 'C', :$strict = 1, :$tz = 'UTC') {
  10 50       68  
  10 100       27  
  10 50       39  
  10 50       31  
  10 50       38  
  10         33  
  10         34  
  10         44  
  10         21  
222 10         46 my %p = _parse($str, $format, $tz, locale => $locale, strict => $strict);
223              
224 10         76 return $c->mktime(%p);
225             }
226              
227              
228 181 50 66 181 1 17709 method strptime ($c: $str, $format, :$locale = 'C', :$strict = 1) {
  181 50       636  
  181 100       291  
  181 50       421  
  181 50       465  
  181         406  
  181         446  
  181         262  
229 181         262 my %struct;
230 181 100       417 if (ref $c) {
231 10         17 my $t = $c;
232 10 100       29 if ($t->{year}) { $struct{year} = $t->year; }
  4         13  
233 10 100       39 if ($t->{month}) { $struct{month} = $t->month; }
  7         17  
234 10 100       40 if ($t->{mday}) { $struct{mday} = $t->day; }
  5         12  
235 10 100       37 if ($t->{week}) { $struct{week} = $t->week; }
  3         11  
236 10 100       32 if ($t->{wday}) { $struct{wday} = $t->day_of_week; }
  3         12  
237 10 100       33 if ($t->{yday}) { $struct{yday} = $t->day_of_year; }
  2         6  
238 10 100       33 if ($t->{hour}) { $struct{hour} = $t->hour; }
  8         16  
239 10 100       39 if ($t->{minute}) { $struct{minute} = $t->minute; }
  8         18  
240 10 100       41 if ($t->{second}) { $struct{second} = $t->second; }
  8         16  
241 10 100       41 if ($t->{tz_d}) { $struct{tz} = $t->{tz}; }
  2         5  
242 10 50       30 if ($t->{offset}) { $struct{offset} = $t->offset; }
  0         0  
243             }
244 181         674 %struct = Time::P::strptime($str, $format, locale => $locale, strict => $strict, struct => \%struct);
245              
246 181 100       507 if (ref $c) {
247 10         15 my $t = $c;
248              
249 10 100       34 if (defined $struct{tz}) {
    50          
250 2         8 $t->tz = $struct{tz};
251             } elsif (defined $struct{offset}) {
252 0         0 $t->offset = $struct{offset};
253             }
254              
255 10 50       36 if (defined $struct{epoch}) { return $t->epoch($struct{epoch}); }
  0         0  
256              
257 10 100       25 if (defined $struct{year}) { $t->year = $struct{year}; }
  6         20  
258              
259 10 100       38 if (defined $struct{month}) {
    50          
    0          
260 9         22 $t->month = $struct{month};
261 9 100       39 if (defined $struct{mday}) { $t->day = $struct{mday}; }
  7         16  
262             } elsif (defined $struct{week}) {
263 1         4 $t->week = $struct{week};
264 1 50       5 if (defined $struct{wday}) { $t->day_of_week = $struct{wday}; }
  1         5  
265             } elsif (defined $struct{yday}) {
266 0         0 $t->day_of_year = $struct{yday};
267             }
268              
269 10 50       40 if (defined $struct{hour}) { $t->hour = $struct{hour}; }
  10         28  
270 10 50       42 if (defined $struct{minute}) { $t->minute = $struct{minute}; }
  10         25  
271 10 50       41 if (defined $struct{second}) { $t->second = $struct{second}; }
  10         27  
272              
273 10         64 return $t;
274             } else {
275 171         852 return $c->mktime(%struct);
276             }
277             }
278              
279 706 50   706   1991 fun _verify_tz ($tz) {
  706 50       1540  
  706         1248  
  706         981  
280 706         1740 _get_offset(time, $tz);
281             }
282              
283             my %tz_offset = (
284             -720 => 'Etc/GMT+12',
285             -660 => 'Etc/GMT+11',
286             -600 => 'Etc/GMT+10',
287             -540 => 'Etc/GMT+9',
288             -480 => 'Etc/GMT+8',
289             -420 => 'Etc/GMT+7',
290             -360 => 'Etc/GMT+6',
291             -300 => 'Etc/GMT+5',
292             -240 => 'Etc/GMT+4',
293             -180 => 'Etc/GMT+3',
294             -120 => 'Etc/GMT+2',
295             -60 => 'Etc/GMT+1',
296             0 => 'UTC',
297             60 => 'Etc/GMT-1',
298             120 => 'Etc/GMT-2',
299             180 => 'Etc/GMT-3',
300             240 => 'Etc/GMT-4',
301             300 => 'Etc/GMT-5',
302             360 => 'Etc/GMT-6',
303             420 => 'Etc/GMT-7',
304             480 => 'Etc/GMT-8',
305             540 => 'Etc/GMT-9',
306             600 => 'Etc/GMT-10',
307             660 => 'Etc/GMT-11',
308             720 => 'Etc/GMT-12',
309             780 => 'Etc/GMT-13',
310             840 => 'Etc/GMT-14',
311             );
312              
313 4 50   4   22 fun _get_tz ($offset) {
  4 50       19  
  4         13  
  4         11  
314 4 100       73 return 'UTC' unless $offset;
315              
316 3 50       33 return $tz_offset{$offset} if defined $tz_offset{$offset};
317              
318 0         0 my $min = $offset % 60;
319 0         0 my $hour = int $offset / 60;
320 0         0 my $sign = '+';
321 0 0       0 if ($hour < 0) { $sign = '-'; $hour = -$hour; }
  0         0  
  0         0  
322              
323 0         0 return sprintf "%s%02s:%02s", $sign, $hour, $min;
324             }
325              
326 13 50 33 13   48 fun _parse ($str, $format = undef, $tz = 'UTC', :$locale = 'C', :$strict = 1) {
  13 50       102  
  13 50       96  
  13 50       65  
  13 50       61  
  13 50       52  
  13         27  
327 13 100       47 if (defined $format) {
328 4         14 my %struct = ();
329 4         14 my $e = eval { %struct = Time::P::strptime($str, $format, locale => $locale, strict => $strict); 1; };
  4         30  
  4         14  
330 4 50       40 return %struct if $e;
331              
332 0         0 croak sprintf "Could not parse %s using %s: %s", $str, $format, $@;
333             }
334              
335 9         23 my $tm = eval { Time::Moment->from_string($str); };
  9         146  
336 9 50       42 croak sprintf "Could not parse %s.", $str if not defined $tm;
337              
338 9         48 my $epoch = $tm->epoch;
339 9         41 my $offset = $tm->offset;
340              
341 9         43 my @ret = (epoch => $epoch, offset => $offset);
342 9 100       82 if ($offset == Time::Zone::Olson->new({timezone => $tz})->local_offset($epoch)) {
343 7         7151 push @ret, tz => $tz;
344             }
345              
346 9         1342 return @ret;
347             }
348              
349              
350              
351 958 50   958 1 7274 method epoch ($t: $new_epoch = undef) :lvalue {
  958 50       1957  
  958         1454  
  958         1698  
  958         1252  
352 958         1579 my $epoch = $t->{epoch};
353              
354             my $setter = sub {
355 2     2   7 $t->{epoch} = $_[0];
356              
357 2         35 %$t = (%$t, epoch_d => 1, year => 1, yday => 1, month => 1, mday => 1, week => 1, wday => 1, hour => 1, minute => 1, second => 1, );
358              
359 2 50       10 return $t if defined $new_epoch;
360 2         7 return $_[0];
361 958         2609 };
362              
363 958 50       2203 return $setter->($new_epoch) if defined $new_epoch;
364              
365 958         2345 sentinel value => $epoch, set => $setter;
366             }
367              
368              
369 35 50   35 1 4959 method tz ($t: $new_tz = undef, $override = 0) :lvalue {
  35 50       93  
  35 100       53  
  35         119  
  35         52  
370             my $setter = sub {
371 35     35   99 _verify_tz($_[0]);
372              
373 35 100       93 if ($override) {
374 25         69 my $l = Time::C->new($t->year, $t->month, $t->day, $t->hour, $t->minute, $t->second, $_[0]);
375 25         315 $t->{epoch} = $l->epoch;
376             }
377              
378 35         178 $t->{tz} = $_[0];
379 35         70 $t->{tz_d} = 1;
380              
381 35 100       189 return $t if defined $new_tz;
382 10         41 return $t->{tz};
383 35         138 };
384              
385 35 100       116 return $setter->($new_tz) if defined $new_tz;
386              
387 10         119 sentinel value => $t->{tz}, set => $setter;
388             }
389              
390 784 50   784   1741 fun _get_offset ($epoch, $tz) {
  784 50       1684  
  784         1434  
  784         1111  
391 784         1543 my $offset = eval { Time::Zone::Olson->new({timezone => $tz})
  784         4687  
392             ->local_offset($epoch); };
393              
394 784 50       362370 if (not defined $offset) {
395 0 0       0 if ($tz =~ /^([+-])(\d+):(\d+)$/) {
396 0         0 my ($sign, $hour, $min) = ($1, $2, $3);
397 0         0 $offset = 60 * $hour + $min;
398 0 0       0 $offset = -$offset if $sign eq '-';
399             }
400             }
401              
402 784 50       2184 croak sprintf "Unknown timezone %s.", $tz
403             if not defined $offset;
404              
405 784         1624 return $offset;
406             }
407              
408              
409 58 50   58 1 5049 method offset ($t: $new_offset = undef) :lvalue {
  58 50       188  
  58         142  
  58         152  
  58         113  
410             my $setter = sub {
411 4     4   22 $t->{tz} = _get_tz($_[0]);
412 4         13 $t->{offset} = 1;
413              
414 4 50       19 return $t if defined $new_offset;
415 4         19 return $_[0];
416 58         279 };
417              
418 58 50       201 return $setter->($new_offset) if defined $new_offset;
419              
420 58         211 my $offset = _get_offset($t->{epoch}, $t->{tz});
421              
422 58         287 sentinel value => $offset, set => $setter;
423             }
424              
425              
426 7354 50   7354 1 20629 method tm ($t: $new_tm = undef) :lvalue {
  7354 50       14206  
  7354         10086  
  7354         10706  
  7354         9126  
427             my $setter = sub {
428 1     1   4 $t->_tm = $_[0];
429 1         10 $t->epoch = $t->epoch; # update definedness values
430              
431 1 50       9 return $t if defined $new_tm;
432 1         3 return $_[0];
433 7354         20634 };
434              
435 7354 50       16046 return $setter->($new_tm) if defined $new_tm;
436              
437 7354         13730 sentinel value => $t->_tm(), set => $setter;
438             }
439              
440 9788 50   9788   20140 method _tm ($t: $new_tm = undef) :lvalue {
  9788 50       18496  
  9788         13104  
  9788         14624  
  9788         11744  
441 9788 50       21157 $t->{tz} = 'UTC' if not defined $t->{tz};
442              
443             my $setter = sub {
444 2434     2434   7397 $t->{epoch} = $_[0]->with_offset_same_instant(0)->epoch;
445              
446 2434 50       5517 return $t if defined $new_tm;
447 2434         7916 return $_[0];
448 9788         22767 };
449              
450 9788 50       21249 return $setter->($new_tm) if defined $new_tm;
451              
452 9788         28198 my $tm = Time::Moment->from_epoch($t->{epoch});
453              
454 9788 100 66     41063 if ($t->{tz} ne 'GMT' and $t->{tz} ne 'UTC') {
455 44         151 $tm = $tm->with_offset_same_instant($t->offset);
456             }
457              
458 9788         23953 sentinel value => $tm, set => $setter;
459             }
460              
461              
462             # need to parse the @args specially since F::P can't handle the signature
463 748 50   748 1 4301 method string ($t: @args) :lvalue {
  748         1230  
  748         1309  
  748         972  
464 748         1465 my ($new_str, $format, $locale, $strict) = (undef, undef, 'C', 1);
465 748 100       1807 if (@args % 2) { $new_str = shift @args; }
  1         4  
466 748         1470 my %args = @args;
467 748 100       1522 $format = delete $args{format} if exists $args{format};
468 748 100       1519 $locale = delete $args{locale} if exists $args{locale};
469 748 100       1472 $strict = delete $args{strict} if exists $args{strict};
470 748 50       1612 croak sprintf "In method string: no such named parameter: %s", sort keys %args if %args;
471              
472 748 50       1751 $t->{tz} = 'UTC' if not defined $t->{tz};
473              
474             my $setter = sub {
475 3     3   18 my %struct = _parse($_[0], $format, $t->{tz}, locale => $locale, strict => $strict);
476              
477 3 50       29 if (defined $struct{tz}) {
    50          
478 0         0 $t->tz = $struct{tz};
479             } elsif (defined $struct{offset}) {
480 0         0 $t->offset = $struct{offset};
481             }
482              
483 3 50       12 if (defined $struct{epoch}) { return $t->epoch($struct{epoch}); }
  0         0  
484              
485 3 50       11 if (defined $struct{year}) { $t->year = $struct{year}; }
  3         14  
486              
487 3 100       31 if (defined $struct{month}) {
    50          
    0          
488 2         8 $t->month = $struct{month};
489 2 50       15 if (defined $struct{mday}) { $t->day = $struct{mday}; }
  2         9  
490             } elsif (defined $struct{week}) {
491 1         10 $t->week = $struct{week};
492 1 50       14 if (defined $struct{wday}) { $t->day_of_week = $struct{wday}; }
  1         10  
493             } elsif (defined $struct{yday}) {
494 0         0 $t->day_of_year = $struct{yday};
495             }
496              
497 3 50       38 if (defined $struct{hour}) { $t->hour = $struct{hour}; }
  0         0  
498 3 50       14 if (defined $struct{minute}) { $t->minute = $struct{minute}; }
  0         0  
499 3 50       14 if (defined $struct{second}) { $t->second = $struct{second}; }
  0         0  
500              
501 3 100       26 return $t if defined $new_str;
502 2         21 return $_[0];
503 748         2589 };
504              
505 748 100       2009 return $setter->($new_str) if defined $new_str;
506              
507 747         1051 my $str;
508 747 100       1412 if (defined $format) {
509 18         69 $str = Time::F::strftime($t, $format, locale => $locale);
510             } else {
511 729         1426 $str = $t->tm->to_string;
512             }
513              
514 747         3929 sentinel value => $str, set => $setter;
515             }
516              
517              
518 20 50   20 1 114 method strftime ($t: @args) :lvalue { $t->string(@args); }
  20         34  
  20         59  
  20         36  
  20         58  
519              
520              
521 573 50   573 1 6938 method year ($t: $new_year = undef) :lvalue {
  573 50       1221  
  573         842  
  573         964  
  573         721  
522 573         1175 my $tm = $t->tm();
523              
524             my $setter = sub {
525 70     70   422 my $ret = ($t->_tm = $tm->with_year($_[0]))->year;
526 70         270 $t->{year} = 1;
527              
528 70 50       197 return $t if defined $new_year;
529 70         225 return $ret;
530 573         3282 };
531              
532 573 50       1402 return $setter->($new_year) if defined $new_year;
533              
534 573         2254 sentinel value => $tm->year, set => $setter;
535             }
536              
537              
538 6 50   6 1 21 method quarter ($t: $new_quarter = undef) :lvalue {
  6 50       15  
  6         8  
  6         12  
  6         8  
539 6         13 my $tm = $t->tm();
540              
541             my $setter = sub {
542 5     5   27 my $ret = ($t->_tm = $tm->plus_months(3*$_[0] - $tm->month))->quarter;
543 5         15 $t->{month} = 1;
544              
545 5 50       11 return $t if defined $new_quarter;
546 5         13 return $ret;
547 6         31 };
548              
549 6 50       15 return $setter->($new_quarter) if defined $new_quarter;
550              
551 6         47 sentinel value => $tm->quarter, set => $setter;
552             }
553              
554              
555 277 50   277 1 6092 method month ($t: $new_month = undef) :lvalue {
  277 50       583  
  277         398  
  277         455  
  277         360  
556 277         537 my $tm = $t->tm();
557              
558             my $setter = sub {
559 220     220   1027 my $ret = ($t->_tm = $tm->plus_months($_[0] - $tm->month))->month;
560 220         709 $t->{month} = 1;
561              
562 220 50       503 return $t if defined $new_month;
563 220         615 return $ret;
564 277         1511 };
565              
566 277 50       682 return $setter->($new_month) if defined $new_month;
567              
568 277         1048 sentinel value => $tm->month, set => $setter;
569             }
570              
571              
572 1028 50   1028 1 8301 method week ($t: $new_week = undef) :lvalue {
  1028 50       2168  
  1028         1470  
  1028         1711  
  1028         1329  
573 1028         1996 my $tm = $t->tm();
574              
575             my $setter = sub {
576 323     323   1468 my $ret = ($t->_tm = $tm->plus_weeks($_[0] - $tm->week))->week;
577 323         1438 $t->{week} = 1;
578              
579 323 100       1385 return $t if defined $new_week;
580 45         160 return $ret;
581 1028         5461 };
582              
583 1028 100       2631 return $setter->($new_week) if defined $new_week;
584              
585 750         2836 sentinel value => $tm->week, set => $setter;
586             }
587              
588              
589 651 50   651 1 6524 method day ($t: $new_day = undef) :lvalue { $t->day_of_month(@_) }
  651 50       1326  
  651         1061  
  651         1091  
  651         867  
  651         1444  
590              
591              
592 657 50   657 1 1409 method day_of_month ($t: $new_day = undef) :lvalue {
  657 50       1317  
  657         1030  
  657         1082  
  657         847  
593 657         1285 my $tm = $t->tm();
594              
595             my $setter = sub {
596 601     601   2492 my $ret = ($t->_tm = $tm->plus_days($_[0] - $tm->day_of_month))->day_of_month;
597 601         1926 $t->{mday} = 1;
598              
599 601 50       1283 return $t if defined $new_day;
600 601         2980 return $ret;
601 657         3374 };
602              
603 657 50       1829 return $setter->($new_day) if defined $new_day;
604              
605 657         2346 sentinel value => $tm->day_of_month, set => $setter;
606             }
607              
608              
609 735 50   735 1 11722 method day_of_year ($t: $new_day = undef) :lvalue {
  735 50       1498  
  735         1038  
  735         1223  
  735         943  
610 735         1305 my $tm = $t->tm();
611              
612             my $setter = sub {
613 172     172   867 my $ret = ($t->_tm = $tm->plus_days($_[0] - $tm->day_of_year))->day_of_year;
614 172         635 $t->{yday} = 1;
615              
616 172 100       829 return $t if defined $new_day;
617 5         15 return $ret;
618 735         3640 };
619              
620 735 100       1828 return $setter->($new_day) if defined $new_day;
621              
622 568         1827 sentinel value => $tm->day_of_year, set => $setter;
623             }
624              
625              
626 3 50   3 1 12 method day_of_quarter ($t: $new_day = undef) :lvalue {
  3 50       8  
  3         5  
  3         7  
  3         3  
627 3         8 my $tm = $t->tm();
628              
629             my $setter = sub {
630 2     2   12 my $ret = ($t->_tm = $tm->plus_days($_[0] - $tm->day_of_quarter))->day_of_quarter;
631 2         7 $t->{mday} = 1;
632              
633 2 50       6 return $t if defined $new_day;
634 2         6 return $ret;
635 3         17 };
636              
637 3 50       9 return $setter->($new_day) if defined $new_day;
638              
639 3         15 sentinel value => $tm->day_of_quarter, set => $setter;
640             }
641              
642              
643 2371 50   2371 1 13152 method day_of_week ($t: $new_day = undef) :lvalue {
  2371 50       4577  
  2371         3409  
  2371         3782  
  2371         3014  
644 2371         4281 my $tm = $t->tm();
645              
646             my $setter = sub {
647 878     878   3475 my $ret = ($t->_tm = $tm->plus_days($_[0] - $tm->day_of_week))->day_of_week;
648 878         2622 $t->{wday} = 1;
649              
650 878 100       3143 return $t if defined $new_day;
651 438         1912 return $ret;
652 2371         11642 };
653              
654 2371 100       5915 return $setter->($new_day) if defined $new_day;
655              
656 1931         6276 sentinel value => $tm->day_of_week, set => $setter;
657             }
658              
659              
660 110 50   110 1 5730 method hour ($t: $new_hour = undef) :lvalue {
  110 50       275  
  110         181  
  110         203  
  110         152  
661 110         240 my $tm = $t->tm();
662              
663             my $setter = sub {
664 64     64   389 my $ret = ($t->_tm = $tm->plus_hours($_[0] - $tm->hour))->hour;
665 64         242 $t->{hour} = 1;
666              
667 64 50       186 return $t if defined $new_hour;
668 64         187 return $ret;
669 110         704 };
670              
671 110 50       287 return $setter->($new_hour) if defined $new_hour;
672              
673 110         430 sentinel value => $tm->hour, set => $setter;
674             }
675              
676              
677 102 50   102 1 5758 method minute ($t: $new_minute = undef) :lvalue {
  102 50       250  
  102         211  
  102         216  
  102         142  
678 102         230 my $tm = $t->tm();
679              
680             my $setter = sub {
681 60     60   338 my $ret = ($t->_tm = $tm->plus_minutes($_[0] - $tm->minute))->minute;
682 60         233 $t->{minute} = 1;
683              
684 60 50       160 return $t if defined $new_minute;
685 60         185 return $ret;
686 102         612 };
687              
688 102 50       292 return $setter->($new_minute) if defined $new_minute;
689              
690 102         427 sentinel value => $tm->minute, set => $setter;
691             }
692              
693              
694 68 50   68 1 5834 method second ($t: $new_second = undef) :lvalue {
  68 50       241  
  68         123  
  68         133  
  68         90  
695 68         149 my $tm = $t->tm();
696              
697             my $setter = sub {
698 27     27   152 my $ret = ($t->_tm = $tm->plus_seconds($_[0] - $tm->second))->second;
699 27         106 $t->{second} = 1;
700              
701 27 100       81 return $t if defined $new_second;
702 25         74 return $ret;
703 68         392 };
704              
705 68 100       183 return $setter->($new_second) if defined $new_second;
706              
707 66         259 sentinel value => $tm->second, set => $setter;
708             }
709              
710              
711 13 50   13 1 48 method second_of_day ($t: $new_second = undef) :lvalue {
  13 50       35  
  13         24  
  13         25  
  13         18  
712 13         31 my $tm = $t->tm();
713              
714             my $setter = sub {
715 11     11   67 my $ret = ($t->_tm = $tm->plus_seconds($_[0] - $tm->second_of_day))->second_of_day;
716 11         44 $t->{second} = $t->{minute} = $t->{hour} = 1;
717              
718 11 100       62 return $t if defined $new_second;
719 3         11 return $ret;
720 13         82 };
721              
722 13 100       46 return $setter->($new_second) if defined $new_second;
723              
724 5         24 sentinel value => $tm->second_of_day, set => $setter;
725             }
726              
727              
728              
729 1 50   1 1 6 method diff ($t: $t2) {
  1 50       4  
  1         2  
  1         3  
  1         1  
730 1 50       15 my $epoch =
    50          
731             ref $t2 ?
732             $t2->can('epoch') ?
733             $t2->epoch :
734             croak "Object with no ->epoch method passed (". ref $t2 .")." :
735             $t2;
736 1         8 return Time::D->new($t->epoch, $epoch);
737             }
738              
739              
740 539 50   539 1 1210 method clone($t:) {
  539 50       1107  
  539         904  
  539         737  
741 539         929 my $c = ref $t;
742              
743 539         4429 my $t2 = { %$t };
744 539         1756 bless $t2, $c;
745             }
746              
747             1;
748              
749             __END__