File Coverage

blib/lib/Date/Fmtstr2time.pm
Criterion Covered Total %
statement 12 198 6.0
branch 0 68 0.0
condition 0 30 0.0
subroutine 4 53 7.5
pod 1 1 100.0
total 17 350 4.8


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Date::Fmtstr2time - Functions to format date/time strings into a Perl Time based on a "Picture" format string.
4              
5             =head1 AUTHOR
6              
7             Jim Turner
8              
9             (c) 2015, Jim Turner under the same license that Perl 5 itself is. All rights reserved.
10              
11             =head1 SYNOPSIS
12              
13             use Date::Fmtstr2time;
14              
15             print str2time('12-25-2015 07:15 AM', 'mm-dd-yyyy hh:mi PM');
16              
17             =head1 DESCRIPTION
18              
19             Date::Fmtstr2time provides a single function B that accepts a date or date / time
20             in a string (I) and a I consisting of special substrings which represent
21             the various parts of a date and time value. It returns a standard Perl (Unix) "time" value (a
22             large integer equivalent to the number of seconds since 1980).
23              
24             =head1 METHODS
25              
26             =over 4
27              
28             =item <$integer> = B(I, I);
29              
30             Returns a standard Perl (Unix) "time" value (a large integer). The I tells
31             the software what format to expect the date / time value in the I to be in.
32              
33             For example:
34              
35             $s = B('01-09-2016 01:20 AM (Sat) (January)', 'mm-dd-yyyy hh:mi PM (Day) (Month)');
36              
37             would set $s to 1452324000, (the Unix time equivalent).
38              
39             =item B
40              
41             There are numerous choices of special format substrings which can be used in an infinite
42             number of combinations to produce the desired results. They are listed below:
43              
44             =over 4
45              
46             B - The Full name of the month in all lower case, ie. "january".
47              
48             B - The Full name of the month capitalized, ie. "January".
49              
50             B - The Full name of the month all capitalized, ie. "JANUARY".
51              
52             B - Day of the week in all lower case, ie. "sunday".
53              
54             B - Day of the week capitalized, ie. "Sunday".
55              
56             B - Day of the week all capitalized, ie. "SUNDAY".
57              
58             B - Three letter abbreviation of the day of the week in all lower case, ie. "sun".
59              
60             B - Three letter abbreviation of the day of the week capitalized, ie. "Sun".
61              
62             B - Three letter abbreviation of the day of the week all capitalized, ie. "SUN".
63              
64             B - Num. of days since beginning of year.
65              
66             B
- Day of month (2 digits, left padded with a zero if needed), ie. "01".
67              
68             B - Day of month (1 or 2 digits, as needed), ie. "1".
69              
70             B, B - Numeric day of the week zero-based (Sunday=0, Monday=1, ... Saturday=6).
71              
72             B - Numeric day of the week one-based (Sunday=1, Monday=2, ... Saturday=7).
73              
74             B - Numeric date in 8 digits, ie. "20150107" for January 7, 2015.
75              
76             B, B - Year in 4 digits.
77              
78             B, B - Year in last 2 digits.
79              
80             B - Military time (hours and minutes: 24 hours, no colon).
81              
82             B - Hour in common format, ie. 01-12.
83              
84             B

- Hour in common format, 1 or 2 digits, as needed, ie. 1-12.

85              
86             B - Minute, ie. 00-59.
87              
88             B - Number of month (2 digits, left padded with a zero if needed), ie. "01" for January.
89              
90             B - Three letter abbreviation of the month, in lower case, ie. "jan" for January.
91              
92             B - Hour in 24-hour format, 2 digits, left padded with a zero if needed, ie. 00-23.
93              
94             B

- Hour in 24-hour format, 1 or 2 digits, as needed, ie. 0-23.

95              
96             B - Three letter abbreviation of the month, capitalized, ie. "Jan" for January.
97              
98             B - Three letter abbreviation of the month all capitalized, ie. "JAN".
99              
100             B - Number of month (1 or 2 digits, as needed), ie. "1" for January.
101              
102             B - Seconds since start of day.
103              
104             B - Seconds since start of last minute (2 digits), ie. 00-59.
105              
106             B, B - display "am" if between Midnight and Noon, "pm" otherwise (both specifiers are identical).
107              
108             B, B - display "AM" if between Midnight and Noon, "PM" otherwise (both specifiers are identical).
109              
110             B, B

- display "a" if between Midnight and Noon, "p" otherwise (both specifiers are identical).

111              
112             B, B

- display "A" if between Midnight and Noon, "P" otherwise (both specifiers are identical).

113              
114             B - Roman numeral for the month (i-xii) in lower case.
115              
116             B - Roman numeral for the month (I-XII) in upper case.
117              
118             B - Number of week of the year (00-51).
119              
120             B - Number of the quarter of the year - (1-4).
121              
122             =back
123              
124             =back
125              
126             =head1 KEYWORDS
127              
128             L, L, formatting, picture_clause, strings
129              
130             =cut
131              
132             package Date::Fmtstr2time;
133              
134 1     1   20721 use strict;
  1         2  
  1         28  
135             #use warnings;
136 1     1   5 use vars qw(@ISA @EXPORT $VERSION);
  1         1  
  1         65  
137             $VERSION = '1.00';
138              
139 1     1   1526 use Time::Local;
  1         1638  
  1         294  
140              
141             require Exporter;
142              
143             @ISA = qw(Exporter);
144             @EXPORT = qw(str2time);
145              
146             my @inputs = ();
147             my @today = ();;
148             my $rtnTime = '';
149             my @tl = ();
150             my $begofyear;
151             my %mthhash = (
152             'january' => '0',
153             'february' => 1,
154             'march' => 2,
155             'april' => 3,
156             'may' => 4,
157             'june' => 5,
158             'july' => 6,
159             'august' => 7,
160             'september' => 8,
161             'october' => 9,
162             'november' => 10,
163             'december' => 11
164             );
165              
166             sub str2time
167             {
168 0     0 1   my ($s) = $_[0];
169 0           my ($f) = $_[1];
170              
171 0           my @fmts = split(/\b/o, $f);
172 0           @inputs = split(/\b/o, $s);
173 0           @today = localtime(time);
174 0           my $err = '';
175 0           $rtnTime = '';
176 0           @tl = ();
177 0           $begofyear = timelocal(0,0,0,1,0,$today[5]);
178              
179 0           my $fn;
180 0           for (my $i=0;$i<=$#fmts;$i++)
181             {
182 0           foreach my $f (qw(month Month MONTH dayofweek Dayofweek DAYOFWEEK day Day DAY ddd
183             ddmm dd d1 d0 mmddyyyy yyyymmdd yyyymm yymmdd mmyyyy mmddyy yyyy yymm mmyy yy hh24 hh
184             HH h1 H1 mi mm mon Mon MON m1 sssss ss am pm AM PM a p A P rm RM rr d ww q))
185             {
186 0 0         if ($fmts[$i] =~ /^$f/i)
187             {
188 0           $fn = '_tod_'.$f;
189 1     1   6 no strict 'refs';
  1         1  
  1         2945  
190 0           $err .= &$fn($i);
191 0           last;
192             }
193             }
194             }
195 0 0         $tl[3] = '1' unless ($tl[3]);
196 0           my $rt = timelocal(@tl);
197              
198 0 0         return ($#tl >= 5) ? timelocal(@tl) : $rtnTime;
199             }
200              
201             sub _tod_month
202             {
203 0     0     my $indx = shift;
204 0           $inputs[$indx] =~ tr/A-Z/a-z/;
205 0           $tl[4] = $mthhash{$inputs[$indx]};
206 0 0         return "Invalid Month ($inputs[$indx])! " unless (length($tl[4]));
207 0           return '';
208             }
209              
210             sub _tod_mon
211             {
212 0     0     my %mthhash = (
213             'jan' => '0',
214             'feb' => 1,
215             'mar' => 2,
216             'apr' => 3,
217             'may' => 4,
218             'jun' => 5,
219             'jul' => 6,
220             'aug' => 7,
221             'sep' => 8,
222             'oct' => 9,
223             'nov' => 10,
224             'dec' => 11
225             );
226              
227 0           my $indx = shift;
228 0           $inputs[$indx] =~ tr/A-Z/a-z/;
229 0           $tl[4] = $mthhash{substr($inputs[$indx],0,3)};
230 0 0         return "Invalid Mth ($inputs[$indx])! " unless (length($tl[4]));
231 0           return '';
232             }
233              
234             sub _tod_rm
235             {
236 0     0     my $indx = shift;
237              
238 0           my %mthhash = (
239             'i' => '0',
240             'ii' => 1,
241             'iii' => 2,
242             'iv' => 3,
243             'v' => 4,
244             'vi' => 5,
245             'vii' => 6,
246             'viii' => 7,
247             'ix' => 8,
248             'x' => 9,
249             'xi' => 10,
250             'xii' => 11
251             );
252              
253 0           $inputs[$indx] =~ tr/A-Z/a-z/;
254 0           $tl[4] = $mthhash{$inputs[$indx]};
255 0 0         return "Invalid Roman Mth. ($inputs[$indx])! " unless (length($tl[4]));
256 0           return '';
257             }
258              
259             sub _tod_mm
260             {
261 0     0     my $indx = shift;
262 0           $inputs[$indx] =~ s/^0//;
263 0 0 0       return "Invalid month ($inputs[$indx])! "
264             unless ($inputs[$indx] > 0 && $inputs[$indx] <= 12);
265 0           $tl[4] = $inputs[$indx] - 1;
266 0           return '';
267             }
268              
269             sub _tod_m1
270             {
271 0     0     return &_tod_mm(@_);
272             }
273              
274             sub _tod_yyyymmdd
275             {
276 0     0     my $indx = shift;
277 0           $tl[5] = substr($inputs[$indx],0,4) - 1900;
278 0           $tl[4] = substr($inputs[$indx],4,2) - 1;
279 0           $tl[3] = substr($inputs[$indx],6,2);
280 0           return '';
281             }
282              
283             sub _tod_yyyymm
284             {
285 0     0     my $indx = shift;
286 0           $tl[5] = substr($inputs[$indx],0,4) - 1900;
287 0           $tl[4] = substr($inputs[$indx],4,2) - 1;
288 0           return '';
289             }
290              
291             sub _tod_yymmdd
292             {
293 0     0     my $indx = shift;
294 0           &_tod_rr($indx);
295 0           $tl[4] = substr($inputs[$indx],2,2) - 1;
296 0           $tl[3] = substr($inputs[$indx],4,2);
297 0           return '';
298             }
299              
300             sub _tod_yymm
301             {
302 0     0     my $indx = shift;
303 0           &_tod_rr($indx);
304 0           $tl[4] = substr($inputs[$indx],2,2) - 1;
305 0           return '';
306             }
307              
308             sub _tod_mmyyyy
309             {
310 0     0     my $indx = shift;
311 0           &_tod_mm($indx);
312 0           $inputs[$indx] = substr($inputs[$indx],2,4);
313 0           $tl[5] = substr($inputs[$indx],2,4) - 1900;
314 0           return '';
315             }
316              
317             sub _tod_mmyy
318             {
319 0     0     my $indx = shift;
320 0           &_tod_mm($indx);
321 0           $inputs[$indx] = substr($inputs[$indx],2,2);
322 0           &_tod_rr;
323 0           return '';
324             }
325              
326             sub _tod_mmddyyyy
327             {
328 0     0     my $indx = shift;
329 0           &_tod_mm($indx);
330 0           $tl[3] = substr($inputs[$indx],2,2) - 1;
331 0           $tl[5] = substr($inputs[$indx],4,4) - 1900;
332 0           return '';
333             }
334              
335             sub _tod_mmddyy
336             {
337 0     0     my $indx = shift;
338 0           &_tod_mm($indx);
339 0           $tl[3] = substr($inputs[$indx],2,2) - 1;
340 0           $inputs[$indx] =~ substr($inputs[$indx],4,2);
341 0           &_tod_rr($indx);
342 0           return '';
343             }
344              
345             sub _tod_mmdd
346             {
347 0     0     my $indx = shift;
348 0           &_tod_mm($indx);
349 0           $tl[3] = substr($inputs[$indx],2,2);
350 0           return '';
351             }
352              
353             sub _tod_ddmm
354             {
355 0     0     my $indx = shift;
356 0           &_tod_dd($indx);
357 0           $tl[4] = substr($inputs[$indx],2,2) - 1;
358 0           return '';
359             }
360              
361             sub _tod_yyyy
362             {
363 0     0     my $indx = shift;
364 0 0         return "Invalid year ($inputs[$indx])! "
365             unless ($inputs[$indx] =~ /^\d\d\d\d$/);
366 0           $tl[5] = $inputs[$indx] - 1900;
367 0           return '';
368             }
369              
370             sub _tod_yy
371             {
372 0     0     return &_tod_rr(shift);
373             }
374              
375             sub _tod_rr
376             {
377 0     0     my $indx = shift;
378 0 0         return "Invalid year ($inputs[$indx])! "
379             unless ($inputs[$indx] =~ /^\d\d$/);
380 0 0         if (($today[5] % 100) > 50)
381             {
382 0 0         $inputs[$indx] += 100 if ($inputs[$indx] < 50);
383             }
384             else
385             {
386             #$inputs[$indx] -= 100 if ($inputs[$indx] > 50);
387 0 0         $inputs[$indx] += 100 if ($inputs[$indx] < 50);
388             }
389 0           $tl[5] = $inputs[$indx];
390 0           return '';
391             }
392              
393             sub _tod_rrrr
394             {
395 0     0     my $indx = shift;
396 0 0         return &_tod_rr($indx) if ($inputs[$indx] =~ /^\d\d?$/);
397 0 0         return "Invalid year ($inputs[$indx])! "
398             unless ($inputs[$indx] =~ /^\d\d\d\d?$/);
399 0 0         if (($today[5] % 100) > 50)
400             {
401 0 0         $inputs[$indx] += 100 if (($inputs[$indx] % 100) < 50);
402             }
403             else
404             {
405             #$inputs[$indx] -= 100 if (($inputs[$indx] % 100) > 50);
406 0 0         $inputs[$indx] += 100 if ($inputs[$indx] < 50);
407             }
408 0           $tl[5] = $inputs[$indx] - 1900;
409 0           return '';
410             }
411              
412             sub _tod_ddd
413             {
414 0     0     my $indx = shift;
415 0           $inputs[$indx] =~ s/^0+//;
416 0 0 0       return "Invalid year-day ($inputs[$indx])! "
417             unless ($inputs[$indx] > 0 and $inputs[$indx] <= 366);
418 0 0         $rtnTime += $begofyear + (($inputs[$indx]*86400) - 86400) unless ($rtnTime > 86400);
419 0           return '';
420             }
421              
422             sub _tod_dd
423             {
424 0     0     my $indx = shift;
425 0 0 0       return "Invalid day ($inputs[$indx])! "
426             unless ($inputs[$indx] > 0 and $inputs[$indx] <= 31);
427 0           $inputs[$indx] =~ s/^0//;
428 0           $tl[3] = $inputs[$indx];
429 0           return '';
430             }
431              
432             sub _tod_d1
433             {
434 0     0     return &_tod_dd(@_);
435             }
436              
437             sub _tod_hh
438             {
439 0     0     my $indx = shift;
440 0 0 0       return "Invalid hour ($inputs[$indx])! "
441             unless ($inputs[$indx] >= 0 and $inputs[$indx] < 24);
442 0 0         $tl[2] = $inputs[$indx] unless ($tl[2] =~ /\d/);
443 0 0         $rtnTime += ($inputs[$indx] * 3600) if ($rtnTime);
444 0           return '';
445             }
446              
447             sub _tod_h1
448             {
449 0     0     return &_tod_hh(@_);
450             }
451              
452             sub _tod_H1
453             {
454 0     0     return &_tod_hh(@_);
455             }
456              
457             sub _tod_hh24
458             {
459 0     0     my $indx = shift;
460 0 0 0       return "Invalid 24-hr time ($inputs[$indx])! "
      0        
461             unless ($inputs[$indx] >= 0 and $inputs[$indx] <= 2400
462             and ($inputs[$indx] % 100) < 60);
463 0           $tl[1] = ($inputs[$indx] % 100);
464 0           $inputs[$indx] = int($inputs[$indx] / 100);
465 0 0 0       return "Invalid 24-hr time ($inputs[$indx])! "
466             unless ($inputs[$indx] > 0 and $inputs[$indx] < 24);
467 0           $tl[2] = $inputs[$indx];
468 0           return '';
469             }
470              
471             sub _tod_HH
472             {
473 0     0     my $indx = shift;
474 0           return &_tod_hh($indx);
475             }
476              
477             sub _tod_a
478             {
479 0     0     my $indx = shift;
480 0 0         if ($tl[2] < 12)
481             {
482 0 0         $tl[2] += 12 if ($inputs[$indx] =~ /p/io);
483             }
484             else
485             {
486 0 0         $tl[2] -= 12 if ($inputs[$indx] =~ /a/io);
487             }
488 0           return '';
489             }
490              
491             sub _tod_p
492             {
493 0     0     return &_tod_a;
494             }
495              
496             sub _tod_A
497             {
498 0     0     return &_tod_a;
499             }
500              
501             sub _tod_P
502             {
503 0     0     return &_tod_a;
504             }
505              
506             sub _tod_am
507             {
508 0     0     return &_tod_a;
509             }
510              
511             sub _tod_pm
512             {
513 0     0     return &_tod_a;
514             }
515              
516             sub _tod_AM
517             {
518 0     0     return &_tod_a;
519             }
520              
521             sub _tod_PM
522             {
523 0     0     return &_tod_a;
524             }
525              
526             sub _tod_mi
527             {
528 0     0     my $indx = shift;
529 0           $inputs[$indx] =~ s/^0//;
530 0 0 0       return "Invalid minutes ($inputs[$indx])! "
531             unless ($inputs[$indx] >= 0 and $inputs[$indx] <= 59);
532 0           $tl[1] = $inputs[$indx];
533 0 0         $rtnTime += ($inputs[$indx] * 60) if ($rtnTime);
534 0           return '';
535             }
536              
537             sub _tod_sssss
538             {
539 0     0     my $indx = shift;
540 0           $inputs[$indx] =~ s/^0//;
541 0 0 0       return "Invalid seconds ($inputs[$indx])! "
542             unless ($inputs[$indx] >= 0 and $inputs[$indx] <= 86400);
543 0           $tl[2] = int($inputs[$indx] / 3600);
544 0           $tl[0] = $inputs[$indx] % 60;
545 0           $tl[1] = int($inputs[$indx]/60) % 60;
546 0           $rtnTime += $inputs[$indx];
547 0           return '';
548             }
549              
550             sub _tod_ss
551             {
552 0     0     my $indx = shift;
553 0           $inputs[$indx] =~ s/^0//;
554 0 0 0       return "Invalid seconds ($inputs[$indx])! "
555             unless ($inputs[$indx] >= 0 and $inputs[$indx] <= 59);
556 0           $tl[0] = $inputs[$indx];
557 0           $rtnTime += $inputs[$indx];
558 0           return '';
559             }
560              
561             sub _tod_d
562             {
563 0     0     return '';
564             }
565              
566             sub _tod_d0
567             {
568 0     0     return '';
569             }
570              
571             sub _tod_day
572             {
573 0     0     my %dayhash = (
574             'sun' => '0',
575             'mon' => 1,
576             'tue' => 2,
577             'wed' => 3,
578             'thu' => 4,
579             'fri' => 5,
580             'sat' => 6
581             );
582              
583 0           my $indx = shift;
584 0           $inputs[$indx] =~ tr/A-Z/a-z/;
585 0 0         return "Invalid Day ($inputs[$indx])! " unless (defined $mthhash{$inputs[$indx]});
586 0           return '';
587             }
588              
589             sub _tod_Day
590             {
591 0     0     return &_tod_day(@_);
592             }
593              
594             sub _tod_DAY
595             {
596 0     0     return &_tod_day(@_);
597             }
598              
599             sub _tod_dayofweek
600             {
601 0     0     my %dayhash = (
602             'sunday' => '0',
603             'monday' => 1,
604             'tuesday' => 2,
605             'wednesday' => 3,
606             'thursday' => 4,
607             'friday' => 5,
608             'saturday' => 6
609             );
610              
611 0           my $indx = shift;
612 0           $inputs[$indx] =~ tr/A-Z/a-z/;
613 0 0         return "Invalid Day ($inputs[$indx])! " unless (defined $dayhash{$inputs[$indx]});
614 0           return '';
615             }
616              
617             sub _tod_Dayofweek
618             {
619 0     0     return &_tod_day(@_);
620             }
621              
622             sub _tod_DAYOFWEEK
623             {
624 0     0     return &_tod_day(@_);
625             }
626              
627             sub _tod_ww
628             {
629 0     0     return '';
630             }
631              
632             sub _tod_q
633             {
634 0     0     return '';
635             }
636              
637             1