File Coverage

lib/Date/Manip/TZ_Base.pm
Criterion Covered Total %
statement 158 191 82.7
branch 81 110 73.6
condition 9 9 100.0
subroutine 16 16 100.0
pod n/a
total 264 326 80.9


line stmt bran cond sub pod time code
1             package Date::Manip::TZ_Base;
2             # Copyright (c) 2010-2023 Sullivan Beck. All rights reserved.
3             # This program is free software; you can redistribute it and/or modify it
4             # under the same terms as Perl itself.
5              
6             ########################################################################
7             ########################################################################
8              
9             require 5.010000;
10 168     168   1044 use warnings;
  168         269  
  168         4597  
11 168     168   716 use strict;
  168         263  
  168         2533  
12 168     168   613 use IO::File;
  168         252  
  168         19511  
13 168     168   942 use Carp;
  168         261  
  168         311635  
14              
15             our ($VERSION);
16             $VERSION='6.92';
17 168     168   774 END { undef $VERSION; }
18              
19             ########################################################################
20             # METHODS
21             ########################################################################
22              
23             sub _config_var {
24 8230     8230   13692 my($self,$var,$val) = @_;
25 8230         11166 $var = lc($var);
26              
27             # A simple flag used to force a new configuration, but has
28             # no other affect.
29 8230 100       13182 return if ($var eq 'ignore');
30              
31 8224         12152 my $istz = ref($self) eq 'Date::Manip::TZ';
32              
33 8224 100 100     18554 if ($istz && ($var eq 'tz' ||
      100        
34             $var eq 'forcedate' ||
35             $var eq 'setdate' ||
36             $var eq 'configfile')) {
37 384 50       1123 if ($var eq 'tz') {
38 0         0 carp "WARNING: the TZ Date::Manip config variable is deprecated\n" .
39             " and will be removed in version 7.00. Please use\n" .
40             " the SetDate or ForceDate config variables instead.\n";
41             }
42 384         1745 return $self->_config_var_tz($var,$val);
43             } else {
44 7840 100       10788 my $base = ($istz ? $$self{'base'} : $self);
45 7840         15223 return $base->_config_var_base($var,$val);
46             }
47             }
48              
49             # This reads a config file
50             #
51             sub _config_file {
52 27     27   72 my($self,$file) = @_;
53              
54 27 50       125 return if (! $file);
55              
56 27 50       997 if (! -f $file) {
57 0         0 carp "ERROR: [config_file] file doesn't exist: $file";
58 0         0 return;
59             }
60 27 50       371 if (! -r $file) {
61 0         0 carp "ERROR: [config_file] file not readable: $file";
62 0         0 return;
63             }
64              
65 27         285 my $in = new IO::File;
66 27 50       1176 if (! $in->open($file)) {
67 0         0 carp "ERROR: [config_file] unable to open file: $file: $!";
68 0         0 return;
69             }
70 27         12866 my @in = <$in>;
71 27         399 $in->close();
72              
73 27         536 my $sect = 'conf';
74 27         59 my %sect;
75              
76 27         118 chomp(@in);
77 27         88 foreach my $line (@in) {
78 1179         1718 $line =~ s/^\s+//o;
79 1179         1978 $line =~ s/\s+$//o;
80 1179 100 100     3000 next if (! $line or $line =~ /^\043/o);
81              
82 504 100       773 if ($line =~ /^\*/o) {
83             # New section
84 27         237 $sect = $self->_config_file_section($line);
85             } else {
86 477         651 $sect{$sect} = 1;
87 477         857 $self->_config_file_var($sect,$line);
88             }
89             }
90              
91             # If we did a holidays section, we need to create a regular
92             # expression with all of the holiday names.
93              
94 27         82 my $istz = ref($self) eq 'Date::Manip::TZ';
95 27 50       100 my $base = ($istz ? $$self{'base'} : $self);
96              
97 27 100       109 if (exists $sect{'holidays'}) {
98 24         47 my @hol = @{ $$base{'data'}{'sections'}{'holidays'} };
  24         132  
99 24         55 my @nam;
100 24         95 while (@hol) {
101 225         265 my $junk = shift(@hol);
102 225         309 my $hol = shift(@hol);
103 225 100       470 push(@nam,$hol) if ($hol);
104             }
105              
106 24 50       75 if (@nam) {
107 24         147 @nam = sort _sortByLength(@nam);
108 24         71 my $hol = '(?<holiday>' . join('|',map { "\Q$_\E" } @nam) . ')';
  210         419  
109 24         119 my $yr = '(?<y>\d\d\d\d|\d\d)';
110              
111 24         153 my $rx = "$hol\\s*$yr|" . # Christmas 2009
112             "$yr\\s*$hol|" . # 2009 Christmas
113             "$hol"; # Christmas
114              
115 24         7122 $$base{'data'}{'rx'}{'holidays'} = qr/^(?:$rx)$/i;
116             }
117             }
118             }
119              
120             sub _config_file_section {
121 27     27   89 my($self,$line) = @_;
122              
123 27         85 my $istz = ref($self) eq 'Date::Manip::TZ';
124 27 50       99 my $base = ($istz ? $$self{'base'} : $self);
125              
126 27         116 $line =~ s/^\*//o;
127 27         134 $line =~ s/\s*$//o;
128 27         73 my $sect = lc($line);
129 27 50       113 if (! exists $$base{'data'}{'sections'}{$sect}) {
130 0         0 carp "WARNING: [config_file] unknown section created: $sect";
131 0         0 $base->_section($sect);
132             }
133 27         424 return $sect;
134             }
135              
136             sub _config_file_var {
137 477     477   736 my($self,$sect,$line) = @_;
138              
139 477         702 my $istz = ref($self) eq 'Date::Manip::TZ';
140 477 50       766 my $base = ($istz ? $$self{'base'} : $self);
141              
142 477         531 my($var,$val);
143 477 50       2083 if ($line =~ /^\s*(.*?)\s*=\s*(.*?)\s*$/o) {
144 477         1114 ($var,$val) = ($1,$2);
145             } else {
146 0         0 croak "ERROR: invalid Date::Manip config file line:\n $line\n";
147             }
148              
149 477 100       726 if ($sect eq 'conf') {
150 224         310 $var = lc($var);
151 224         385 $self->_config($var,$val);
152             } else {
153 253         536 $base->_section($sect,$var,$val);
154             }
155             }
156              
157             # $val = $self->config(VAR);
158             # Returns the value of a variable.
159             #
160             # $self->config([SECT], VAR, VAL) sets the value of a variable
161             # Sets the value of a variable.
162             #
163             sub _config {
164 47161     47161   92467 my($self,$var,$val) = @_;
165              
166 47161         55460 my $sect = 'conf';
167              
168             #
169             # $self->_conf(VAR, VAL) sets the value of a variable
170             #
171              
172 47161         59783 $var = lc($var);
173 47161 100       68342 if (defined $val) {
174 229         394 return $self->_config_var($var,$val);
175             }
176              
177             #
178             # $self->_conf(VAR) returns the value of a variable
179             #
180              
181 46932 50       88888 if (exists $$self{'data'}{'sections'}{$sect}{$var}) {
182 46932         120919 return $$self{'data'}{'sections'}{$sect}{$var};
183             } else {
184 0         0 carp "ERROR: [config] invalid config variable: $var";
185 0         0 return '';
186             }
187             }
188              
189             ########################################################################
190              
191             sub _fix_year {
192 2665     2665   14876 my($self,$y) = @_;
193 2665         5296 my $istz = ref($self) eq 'Date::Manip::TZ';
194 2665 100       7931 my $base = ($istz ? $self->base() : $self);
195              
196 2665         6552 my $method = $base->_config('yytoyyyy');
197              
198 2665 100       9433 return $y if (length($y)==4);
199 256 50       536 return undef if (length($y)!=2);
200              
201 256         320 my $curr_y;
202 256 100       483 if (ref($self) eq 'Date::Manip::TZ') {
203 241         509 $curr_y = $self->_now('y',1);
204             } else {
205 15         302 $curr_y = ( localtime(time) )[5];
206 15         49 $curr_y += 1900;
207             }
208              
209 256 100       785 if ($method eq 'c') {
    100          
    100          
210 3         15 return substr($curr_y,0,2) . $y;
211              
212             } elsif ($method =~ /^c(\d\d)$/) {
213 3         17 return "$1$y";
214              
215             } elsif ($method =~ /^c(\d\d)(\d\d)$/) {
216 2 100       17 return "$1$y" + ($y<$2 ? 100 : 0);
217              
218             } else {
219 248         524 my $y1 = $curr_y - $method;
220 248         331 my $y2 = $y1 + 99;
221 248         663 $y1 =~ /^(\d\d)/;
222 248         737 $y = "$1$y";
223 248 100       602 if ($y<$y1) {
224 46         57 $y += 100;
225             }
226 248 50       446 if ($y>$y2) {
227 0         0 $y -= 100;
228             }
229 248         680 return $y;
230             }
231             }
232              
233             ###############################################################################
234             # Functions for setting the default date/time
235              
236             # Many date operations use a default time and/or date to set some
237             # or all values. This function may be used to set or examine the
238             # default time.
239             #
240             # _now allows you to get the current date and/or time in the
241             # local timezone.
242             #
243             # The function performed depends on $op and are described in the
244             # following table:
245             #
246             # $op function
247             # ------------------ ----------------------------------
248             # undef Returns the current default values
249             # (y,m,d,h,mn,s) without updating
250             # the time (it'll update if it has
251             # never been set).
252             #
253             # 'now' Updates now and returns
254             # (y,m,d,h,mn,s)
255             #
256             # 'time' Updates now and Returns (h,mn,s)
257             #
258             # 'y' Returns the default value of one
259             # 'm' of the fields (no update)
260             # 'd'
261             # 'h'
262             # 'mn'
263             # 's'
264             #
265             # 'systz' Returns the system timezone
266             #
267             # 'isdst' Returns the 'now' values if set,
268             # 'tz' or system time values otherwise.
269             # 'offset'
270             # 'abb'
271             #
272             sub _now {
273 12980     12980   21076 my($self,$op,$noupdate) = @_;
274 12980         21783 my $istz = ref($self) eq 'Date::Manip::TZ';
275 12980 50       30797 my $base = ($istz ? $self->base() : $self);
276              
277             # Update "NOW" if we're checking 'now', 'time', or the date
278             # is not set already.
279              
280 12980 100       24137 if (! defined $noupdate) {
281 5600 50       9781 if ($op =~ /(?:now|time)/) {
282 0         0 $noupdate = 0;
283             } else {
284 5600         6732 $noupdate = 1;
285             }
286             }
287 12980 100       26358 $noupdate = 0 if (! exists $$base{'data'}{'now'}{'date'});
288 12980 100       23827 $self->_update_now() unless ($noupdate);
289              
290             # Now return the value of the operation
291              
292 12980         14440 my @tmpnow = @{ $$base{'data'}{'tmpnow'} };
  12980         26465  
293 12980 100       24652 my @now = (@tmpnow ? @tmpnow : @{ $$base{'data'}{'now'}{'date'} });
  7406         21876  
294              
295 12980 100       28376 if ($op eq 'tz') {
    50          
    100          
    50          
    50          
    100          
    100          
    100          
    100          
    50          
    0          
    0          
    0          
296 10698 100       17246 if (exists $$base{'data'}{'now'}{'tz'}) {
297 10688         30848 return $$base{'data'}{'now'}{'tz'};
298             } else {
299 10         33 return $$base{'data'}{'now'}{'systz'};
300             }
301              
302             } elsif ($op eq 'systz') {
303 0         0 return $$base{'data'}{'now'}{'systz'};
304              
305             } elsif ($op eq 'isdst') {
306 436         1116 return $$base{'data'}{'now'}{'isdst'};
307              
308             } elsif ($op eq 'offset') {
309 0         0 return @{ $$base{'data'}{'now'}{'offset'} };
  0         0  
310              
311             } elsif ($op eq 'abb') {
312 0         0 return $$base{'data'}{'now'}{'abb'};
313              
314             } elsif ($op eq 'now') {
315 194         771 return @now;
316              
317             } elsif ($op eq 'y') {
318 1519         4314 return $now[0];
319              
320             } elsif ($op eq 'time') {
321 16         61 return @now[3..5];
322              
323             } elsif ($op eq 'm') {
324 61         161 return $now[1];
325              
326             } elsif ($op eq 'd') {
327 56         151 return $now[2];
328              
329             } elsif ($op eq 'h') {
330 0         0 return $now[3];
331              
332             } elsif ($op eq 'mn') {
333 0         0 return $now[4];
334              
335             } elsif ($op eq 's') {
336 0         0 return $now[5];
337              
338             } else {
339 0         0 carp "ERROR: [now] invalid argument list: $op";
340 0         0 return ();
341             }
342             }
343              
344             sub _update_now {
345 2223     2223   3639 my($self) = @_;
346 2223         3948 my $istz = ref($self) eq 'Date::Manip::TZ';
347 2223 50       5426 my $base = ($istz ? $self->base() : $self);
348              
349             # If we've called ForceDate, don't change it.
350 2223 100       6491 return if ($$base{'data'}{'now'}{'force'});
351              
352             # If we've called SetDate (which will only happen if a
353             # Date::Manip:TZ object is available), figure out what 'now' is
354             # based on the number of seconds that have elapsed since it was
355             # set. This will ONLY happen if TZ has been loaded.
356              
357 4 50       14 if ($$base{'data'}{'now'}{'set'}) {
358 0         0 my $date = $$base{'data'}{'now'}{'setdate'};
359 0         0 my $secs = time - $$base{'data'}{'now'}{'setsecs'};
360              
361 0         0 $date = $base->calc_date_time($date,[0,0,$secs]); # 'now' in GMT
362 0         0 my $zone = $self->_now('tz',1);
363 0         0 my ($err,$date2,$offset,$isdst,$abbrev) = $self->convert_from_gmt($date,$zone);
364              
365 0         0 $$base{'data'}{'now'}{'date'} = $date2;
366 0         0 $$base{'data'}{'now'}{'isdst'} = $isdst;
367 0         0 $$base{'data'}{'now'}{'offset'} = $offset;
368 0         0 $$base{'data'}{'now'}{'abb'} = $abbrev;
369 0         0 return;
370             }
371              
372             # Otherwise, we'll use the system time.
373              
374 4         7 my $time = time;
375 4         80 my($s,$mn,$h,$d,$m,$y,$wday,$yday,$isdst) = localtime($time);
376 4         37 my($s0,$mn0,$h0,$d0,$m0,$y0) = gmtime($time);
377              
378 4         9 $y += 1900;
379 4         7 $m++;
380              
381 4         6 $y0 += 1900;
382 4         7 $m0++;
383              
384 4         29 my $off = $base->calc_date_date([$y,$m,$d,$h,$mn,$s],[$y0,$m0,$d0,$h0,$mn0,$s0],1);
385              
386 4         15 $$base{'data'}{'now'}{'date'} = [$y,$m,$d,$h,$mn,$s];
387 4         13 $$base{'data'}{'now'}{'isdst'} = $isdst;
388 4         10 $$base{'data'}{'now'}{'offset'}= $off;
389              
390 4         8 my $abb = '???';
391 4 50       265 if (ref($self) eq 'Date::Manip::TZ') {
392 4         20 my $zone = $self->_now('tz',1);
393 4         24 my $per = $self->date_period([$y,$m,$d,$h,$mn,$s],$zone,1,$isdst);
394 4         14 $abb = $$per[4];
395             }
396              
397 4         12 $$base{'data'}{'now'}{'abb'} = $abb;
398              
399 4         12 return;
400             }
401              
402             ###############################################################################
403             # This sorts from longest to shortest element
404             #
405 168     168   1247 no strict 'vars';
  168         360  
  168         10257  
406             sub _sortByLength {
407 474     474   586 return (length $b <=> length $a);
408             }
409 168     168   1010 use strict 'vars';
  168         295  
  168         6660  
410              
411             1;
412             # Local Variables:
413             # mode: cperl
414             # indent-tabs-mode: nil
415             # cperl-indent-level: 3
416             # cperl-continued-statement-offset: 2
417             # cperl-continued-brace-offset: 0
418             # cperl-brace-offset: 0
419             # cperl-brace-imaginary-offset: 0
420             # cperl-label-offset: 0
421             # End: