File Coverage

blib/lib/Math/Calc/Units/Convert/Date.pm
Criterion Covered Total %
statement 50 60 83.3
branch 19 32 59.3
condition 8 9 88.8
subroutine 9 13 69.2
pod 0 7 0.0
total 86 121 71.0


line stmt bran cond sub pod time code
1             package Math::Calc::Units::Convert::Date;
2 1     1   5 use base 'Math::Calc::Units::Convert::Base';
  1         2  
  1         111  
3 1     1   2110 use Time::Local qw(timegm);
  1         2296  
  1         81  
4 1     1   9 use strict;
  1         3  
  1         34  
5 1     1   5 use vars qw(%units %pref %ranges %total_unit_map);
  1         1  
  1         280  
6              
7             my $min_nice_time = timegm(0, 0, 0, 1, 0, 1975-1900);
8             my $max_nice_time = timegm(0, 0, 0, 1, 0, 2030-1900);
9              
10             %units = ();
11             %pref = ( default => 1 );
12             %ranges = ( timestamp => [ $min_nice_time, $max_nice_time ] );
13              
14             sub major_pref {
15 0     0 0 0 return 2;
16             }
17              
18             # sub major_variants {}
19              
20             # sub variants {}
21              
22 139     139 0 296 sub canonical_unit { return 'timestamp'; }
23              
24             sub unit_map {
25 32     32 0 42 my ($self) = @_;
26 32 50       80 if (keys %total_unit_map == 0) {
27 32         39 %total_unit_map = (%{$self->SUPER::unit_map()}, %units);
  32         113  
28             }
29 32         109 return \%total_unit_map;
30             }
31              
32             sub get_ranges {
33 0     0 0 0 return \%ranges;
34             }
35              
36             sub get_prefs {
37 0     0 0 0 return \%pref;
38             }
39              
40 1     1   5 use vars qw(@MonthNames);
  1         1  
  1         67  
41 1     1   884 BEGIN { @MonthNames = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); }
42             sub construct {
43 7     7 0 11 my ($self, $constructor, $args) = @_;
44              
45             # Allow timestamp(1000347142) or timestamp() for the current time
46 7 100       16 if ($constructor eq 'timestamp') {
47 2 50       27 $args = time if $args eq '';
48 2         17 return [ $args, { 'timestamp' => 1 } ];
49             }
50              
51 5 50       11 return unless $constructor eq 'date';
52              
53             # Accept a very limited range of formats.
54              
55             # Always assume GMT if not given. Currently, do not handle timezones.
56 5         9 $args =~ s/\s+GMT\s+$//;
57              
58 5         5 my ($Mon, $d, $y, $h, $m, $s, $tz, $M);
59 5         6 $tz = 'GMT';
60              
61             # Format 1: [Weekday] Mon DD HH:MM:SS [Timezone] YYYY
62             # (as returned by gmtime and the 'date' command)
63             # The weekday is ignored if given. The timezone is currently ignored.
64 5 100       43 if ($args =~ /^((?:\w\w\w\s+)?)
    100          
    100          
    50          
65             (\w\w\w)\s*
66             (\d+)\s+
67             (\d+):(\d+)[:.](\d+)\s+
68             (\w+)?\s*
69             (\d\d\d\d)$/x)
70             {
71 1         9 (undef, $Mon, $d, $h, $m, $s, $tz, $y) = ($1, $2, $3, $4, $5, $6, $7, $8);
72              
73             # Format 2: Mon DD YYYY
74             } elsif ($args =~ /^(\w\w\w)[\s-]*
75             (\d+)[,\s-]+
76             (\d\d\d\d)$/x)
77             {
78 2         8 ($Mon, $d, $y) = ($1, $2, $3);
79              
80             # Format 3: YYYY-MM-DD HH:MM:SS
81             } elsif ($args =~ /^(\d\d\d\d)-(\d+)-(\d+)\s+
82             (\d+):(\d+)[:.](\d+)$/x)
83             {
84 1         5 ($y, $M, $d, $h, $m, $s) = ($1, $2, $3, $4, $5, $6);
85 1         3 $M--;
86              
87             # Format 4: YYYY-MM-DD
88             } elsif ($args =~ /^(\d\d\d\d)-(\d+)-(\d+)$/) {
89 1         5 ($y, $M, $d) = ($1, $2, $3);
90 1         3 $M--;
91             } else {
92 0         0 die "Unparseable date string '$args'";
93             }
94              
95 5   100     14 $h ||= 0;
96 5   100     15 $m ||= 0;
97 5   100     12 $s ||= 0;
98              
99 5 100       11 if (defined $Mon) {
100 3         5 $M = 0;
101 3         5 foreach (@MonthNames) {
102 30 100       53 last if lc($_) eq lc($Mon);
103 27         25 $M++;
104             }
105 3 50       7 die "Unparseable month '$Mon'" if $M > 11;
106             }
107              
108 5 50 66     65 if (defined($tz) && $tz ne 'GMT') {
109 0         0 warn "Timezones not supported. Assuming GMT.\n";
110             }
111              
112 5         23 my $timestamp = timegm($s, $m, $h, $d, $M, $y-1900);
113 5 50       138 die "Date '$args' is out of range" if $timestamp == -1;
114 5         41 return [ $timestamp, { 'timestamp' => 1 } ];
115             }
116              
117             sub render {
118 0     0 0   my ($self, $mag, $name, $power) = @_;
119 0 0         return "\@$mag" if $power != 1;
120 0 0         return "\@$mag" if $mag < $min_nice_time;
121 0 0         return "\@$mag" if $mag > $max_nice_time;
122 0           return gmtime($mag) . " (\@$mag)";
123             }
124              
125             1;