File Coverage

blib/lib/Time/Fields.pm
Criterion Covered Total %
statement 88 208 42.3
branch 40 114 35.0
condition 20 45 44.4
subroutine 14 32 43.7
pod 1 2 50.0
total 163 401 40.6


line stmt bran cond sub pod time code
1             # 382C8tQ - Time::Fields.pm created by Pip@CPAN.Org as an abstract base
2             # class for more specialized Time objects (Time::Frame && Time::PT).
3             # Notz:
4             # timelocal($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
5             # Unix epoch 1970-2036 or something
6             # PT epoch 1361-2631
7             # potential smaller fields:
8             # kink as 60th-of-a-jink? tink as 60th-of-a-kink? ... X as 60th-of-a-Y
9             # frame 0.0166666666666667 CYMDhmsfjktbpaz
10             # jink 0.000277777777777778 0.3 milliseconds (thousanths)
11             # kink 0.00000462962962962963 5 microseconds (millionths)
12             # tink 0.0000000771604938271605 77 nano seconds (billionths)
13             # blip 0.00000000128600823045267 1 nano second
14             # RealTimeOperatingSystems may need micro or nano second precision
15             # pip 0.0000000000214334705075446 21 pico seconds (trillionths)
16             # ax 0.000000000000357224508459076 0.4 pico seconds
17             # 0.00000000000000595374180765127 6 femtoseconds (10e-15)
18             # 0.0000000000000000992290301275212 99 atto seconds (10e-18)
19             # 0.00000000000000000165381716879202 2 atto seconds
20             # 0.000000000000000000027563619479867 27 zepto -21
21             # 0.000000000000000000000459393657997783 0.5 zepto
22             # 0.00000000000000000000000765656096662972 8 yocto -24
23             # 0.000000000000000000000000127609349443829 0.1 yocto
24             # 0.00000000000000000000000000212682249073048 2 harpo -27
25             # 0.0000000000000000000000000000354470415121746 35 groucho -30
26             # 0.000000000000000000000000000000590784025202911 0.6 groucho
27             # zepto (10e-21) yocto (10e-24) harpo (10e-27) groucho (10e-30)
28             # zeppo (10e-33) gummo (10e-36) chico (10e-39)
29              
30             =head1 NAME
31              
32             Time::Fields - abstract objects to store distinct time fields
33              
34             =head1 VERSION
35              
36             This documentation refers to version 1.2.565EHOV of
37             Time::Fields, which was released on Sun Jun 5 14:17:24:31 2005.
38              
39             =head1 SYNOPSIS
40              
41             package Time::Fields::NewChildPackageOfTimeFields;
42             use base qw(Time::Fields);
43              
44             # NewChildPackageOfTimeFields definition...
45              
46             =head1 DESCRIPTION
47              
48             Time::Fields defines simple time objects with distinct fields for:
49              
50             Century, Year, Month, Day, hour, minute, second, frame, jink, zone
51              
52             along with methods to manipulate those fields && modify their
53             default presentation. Normally, a frame is one 60th-of-a-
54             second && a jink is one 60th-of-a-frame or about 0.3 milliseconds.
55             The plural for 'jink' is 'jinx'. Fields data && methods are
56             meant to be inherited by other classes (namely L &&
57             L) which implement specific useful interpretations of
58             individual Time::Fields.
59              
60             =head1 2DO
61              
62             =over 2
63              
64             =item - use_? filters should get auto-set when unused fields get assigned
65              
66             =item - What else does Fields need?
67              
68             =back
69              
70             =head1 WHY?
71              
72             The reason I created Fields was that I have grown so enamored with
73             Base64 representations of everything around me that I was
74             compelled to write a simple clock utility ( `pt` ) using Base64.
75             This demonstrated the benefit to be gained from time objects with
76             distinct fields && configurable precision. Thus, Time::Fields
77             was written to be the abstract base class for:
78              
79             Time::Frame ( creates objects which represent spans of time )
80             &&
81             Time::PT ( creates objects which represent instants in time )
82              
83             =head1 USAGE
84              
85             Many of Time::Fields's methods have been patterned after the
86             excellent L module written by Matt Sergeant
87             && Jarkko Hietaniemi .
88              
89             =head2 new(, )
90              
91             Time::Fields's constructor can be
92             called as a class method to create a brand new object or as
93             an object method to copy an existing object. Beyond that,
94             new() can initialize Fields objects the following ways:
95              
96             *
97             eg. Time::Fields->new('0123456789');
98             * 'str' =>
99             eg. Time::Fields->new('str' => '0123456789');
100             * 'list' =>
101             eg. Time::Fields->new('list' => [0, 1, 2..9]);
102             * 'hash' =>
103             eg. Time::Fields->new('hash' => {'jink' => 8, 'year' => 2003})
104              
105             b<*Note*> If only a valid 'str'-type parameter is given to new
106             (but no accompanying initialization value), the parameter
107             is interpreted as an implied 'str' value.
108              
109             eg. Time::Fields->new('0123456789');
110              
111             This implied 'str'-type initialization will probably be
112             the most common Time::Fields object creation mechanism
113             when individual fields do not exceed 64 since this
114             efficient representation is why the module was created.
115              
116             The following methods allow access to individual fields of
117             existent Time::Fields objects:
118              
119             $t->C or $t->century
120             $t->Y or $t->year
121             $t->M or $t->month
122             $t->D or $t->day
123             $t->h or $t->hour
124             $t->m or $t->minute
125             $t->s or $t->second
126             $t->f or $t->frame
127             $t->j or $t->jink
128             $t->z or $t->zone
129              
130             Any combination of above single letters can be used as well.
131             Following are some common useful examples:
132              
133             $t->hms # returns list of fields eg. [12, 34, 56]
134             $t->hms(12, 56, 34) # sets fields: h = 12, m = 56, s = 34
135             $t->hmsf # [12, 34, 56, 12]
136             $t->hmsfj # [12, 34, 56, 12, 34]
137             $t->hmsfjz # [12, 34, 56, 12, 34, 16]
138             $t->time # same as $t->hms
139             $t->alltime # same as $t->hmsfjz
140             $t->YMD # [2000, 2, 29]
141             $t->MDY # [ 2, 29, 2000]
142             $t->DMY # [ 29, 2, 2000]
143             $t->CYMD # [ 20, 0, 2, 29]
144             $t->date # same as $t->YMD
145             $t->alldate # same as $t->CYMD
146             $t->CYMDhmsfjz # [ 20, 0, 2, 29, 12, 13, 56, 12, 13, 16]
147             $t->dt # same as $t->CYMDhmsfjz
148             $t->all # same as $t->CYMDhmsfjz
149             "$t" # same as $t->CYMDhmsfjz
150              
151             =head2 Month / minute Exceptions
152              
153             Fields object method names can be in any case with the following
154             exceptions. Special handling exists to resolve ambiguity between
155             the Month && minute fields. If a lowercase 'm' is used adjacent to
156             a 'y' or 'd' of either case, it is interpreted as Month. Otherwise,
157             the case of the 'm' distinguishes Month from minute. An uppercase
158             'M' is ALWAYS Month. An adjacent uppercase 'H' or 'S' will not turn
159             an uppercase 'M' into minute. Method names which need to specify
160             Month or minute fields can also optionally be uniquely specified by
161             their distinguishing vowel ('o' or 'i') instead of 'M' or 'm'.
162              
163             $t->ymd # same as $t->YMD
164             $t->dmy # same as $t->DMY
165             $t->MmMm # Month minute Month minute
166             $t->HMS # hour Month second! NOT same as $t->hms
167             $t->yod # same as $t->YMD
168             $t->chmod # Century hour minute Month Day
169             $t->FooIsMyJoy # frame Month Month minute second
170             # Month Year jink Month Year
171              
172             =head1 NOTES
173              
174             Whenever individual Time::Fields attributes are going to be
175             printed or an entire object can be printed with multi-colors,
176             the following mapping should be employed whenever possible:
177              
178             D Century -> DarkRed
179             A Year -> Red
180             T Month -> Orange
181             E Day -> Yellow
182             hour -> Green
183             t minute -> Cyan
184             i second -> Blue
185             m frame -> Purple
186             e jink -> DarkPurple
187             zone -> Grey or White
188              
189             Even though Time::Fields is designed to be an abstract base class,
190             it has not been written to croak on direct usage && object
191             instantiation because simple Fields objects may already be
192             worthwhile.
193              
194             I hope you find Time::Fields useful. Please feel free to e-mail
195             me any suggestions || coding tips || notes of appreciation
196             ("app-ree-see-ay-shun"). Thank you. TTFN.
197              
198             =head1 CHANGES
199              
200             Revision history for Perl extension Time::Fields:
201              
202             =over 4
203              
204             =item - 1.2.565EHOV Sun Jun 5 14:17:24:31 2005
205              
206             * combined Fields, Frame, && PT into one pkg (so see PT CHANGES section
207             for updates to Fields or Frame)
208              
209             =item - 1.0.3CCA4Eh Fri Dec 12 10:04:14:43 2003
210              
211             * removed indenting from POD NAME field
212              
213             =item - 1.0.3CB7Qb0 Thu Dec 11 07:26:37:00 2003
214              
215             * updated pod && prepared for release
216              
217             =item - 1.0.3CA8oiI Wed Dec 10 08:50:44:18 2003
218              
219             * cleaned up documentation
220              
221             * implemented use methods
222              
223             * overloaded for stringification
224              
225             =item - 1.0.39GHeCl Tue Sep 16 17:40:12:47 2003
226              
227             * incorporated stuff learned from ObjectOrientedPerl (Conway)
228              
229             =item - 1.0.382DLbX Sat Aug 2 13:21:37:33 2003
230              
231             * fleshed out documentation && ideas
232              
233             =item - 1.0.37VG26k Thu Jul 31 16:02:06:46 2003
234              
235             * original version
236              
237             =back
238              
239             =head1 INSTALL
240              
241             Please run:
242              
243             `perl -MCPAN -e "install Time::PT"`
244              
245             or uncompress the package && run the standard:
246              
247             `perl Makefile.PL; make; make test; make install`
248              
249             =head1 FILES
250              
251             Time::Fields requires:
252              
253             L to allow errors to croak() from calling sub
254              
255             L to handle number-base conversion
256              
257             Time::Fields utilizes (if available):
258              
259             L to provide sub-second time precision
260              
261             L to provide Unix time conversion options
262              
263             =head1 SEE ALSO
264              
265             Time::Frame && Time::PT
266              
267             =head1 LICENSE
268              
269             Most source code should be Free!
270             Code I have lawful authority over is && shall be!
271             Copyright: (c) 2003-2004, Pip Stuart.
272             Copyleft : This software is licensed under the GNU General Public
273             License (version 2), && as such comes with NO WARRANTY. Please
274             consult the Free Software Foundation (http://FSF.Org) for
275             important information about your freedom.
276              
277             =head1 AUTHOR
278              
279             Pip Stuart
280              
281             =cut
282              
283             package Time::Fields;
284 1     1   4 use strict;
  1         2  
  1         231  
285 1     1   7 use vars qw( $AUTOLOAD );
  1         1  
  1         234  
286             our $VERSION = '1.2.565EHOV'; # major . minor . PipTimeStamp
287             our $PTVR = $VERSION; $PTVR =~ s/^\d+\.\d+\.//; # strip major && minor
288             # Please see `perldoc Time::PT` for an explanation of $PTVR.
289             use overload
290             q("") => sub { # anonymous stringify()
291 0     0   0 my @fdat = $_[0]->CYMDhmsfjz();
292 0         0 my @attz = $_[0]->_attribute_names();
293 0         0 my $tstr = '';
294 0         0 for(my $i=0; $i<@fdat; $i++) {
295 0         0 $attz[$i] =~ s/^_(.).*/$1/;
296 0 0       0 $attz[$i] = uc($attz[$i]) if($i < 4);
297 0 0       0 $fdat[$i] = 0 unless(defined($fdat[$i]));
298 0         0 $tstr .= $attz[$i] . ':' . $fdat[$i];
299 0 0       0 $tstr .= ', ' if($i < $#fdat);
300             }
301 0         0 return($tstr);
302 1     1   1488 };
  1         1133  
  1         10  
303              
304 1     1   54 use Carp;
  1         2  
  1         72  
305 1     1   857 use Math::BaseCnv qw(:all);
  1         51466  
  1         1652  
306 1     1   917 my $locl = eval("use Time::Local; 1") || 0;
  1         1850  
  1         54  
307 1     1   1005 my $hirs = eval("use Time::HiRes; 1") || 0;
  1         1835  
  1         4  
308             #my $simp = eval("use Curses::Simp; 1") || 0; # ADD to FILES POD if use Simp!
309              
310             # ordered attribute names array, match string for regular expressions, &&
311             # default attribute data hash
312             my @_attrnamz = (); my %_attrmtch = ();
313             my %_attrdata = ();
314             # field data
315             push(@_attrnamz, '_century'); $_attrmtch{$_attrnamz[-1]} = 'C';
316             $_attrdata{$_attrnamz[-1]} = 0;
317             push(@_attrnamz, '_year'); $_attrmtch{$_attrnamz[-1]} = 'Y';
318             $_attrdata{$_attrnamz[-1]} = 0;
319             push(@_attrnamz, '_month'); $_attrmtch{$_attrnamz[-1]} = 'O';
320             $_attrdata{$_attrnamz[-1]} = 0;
321             push(@_attrnamz, '_day'); $_attrmtch{$_attrnamz[-1]} = 'D';
322             $_attrdata{$_attrnamz[-1]} = 0;
323             push(@_attrnamz, '_hour'); $_attrmtch{$_attrnamz[-1]} = 'h';
324             $_attrdata{$_attrnamz[-1]} = 0;
325             push(@_attrnamz, '_minute'); $_attrmtch{$_attrnamz[-1]} = 'i';
326             $_attrdata{$_attrnamz[-1]} = 0;
327             push(@_attrnamz, '_second'); $_attrmtch{$_attrnamz[-1]} = 's';
328             $_attrdata{$_attrnamz[-1]} = 0;
329             push(@_attrnamz, '_frame'); $_attrmtch{$_attrnamz[-1]} = 'f';
330             $_attrdata{$_attrnamz[-1]} = 0;
331             push(@_attrnamz, '_jink'); $_attrmtch{$_attrnamz[-1]} = 'j';
332             $_attrdata{$_attrnamz[-1]} = 0;
333             push(@_attrnamz, '_zone'); $_attrmtch{$_attrnamz[-1]} = 'z';
334             $_attrdata{$_attrnamz[-1]} = 0;
335             # ratios of frames-per-second && jinx-per-frame
336             push(@_attrnamz, '__fps'); $_attrdata{$_attrnamz[-1]} = 60;
337             push(@_attrnamz, '__jpf'); $_attrdata{$_attrnamz[-1]} = 60;
338             # filter flags for which particular fields should be used by default
339             push(@_attrnamz, '__use_century'); $_attrdata{$_attrnamz[-1]} = 0;
340             push(@_attrnamz, '__use_year'); $_attrdata{$_attrnamz[-1]} = 1;
341             push(@_attrnamz, '__use_month'); $_attrdata{$_attrnamz[-1]} = 1;
342             push(@_attrnamz, '__use_day'); $_attrdata{$_attrnamz[-1]} = 1;
343             push(@_attrnamz, '__use_hour'); $_attrdata{$_attrnamz[-1]} = 1;
344             push(@_attrnamz, '__use_minute'); $_attrdata{$_attrnamz[-1]} = 1;
345             push(@_attrnamz, '__use_second'); $_attrdata{$_attrnamz[-1]} = 1;
346             push(@_attrnamz, '__use_frame'); $_attrdata{$_attrnamz[-1]} = 1;
347             push(@_attrnamz, '__use_jink'); $_attrdata{$_attrnamz[-1]} = 0;
348             push(@_attrnamz, '__use_zone'); $_attrdata{$_attrnamz[-1]} = 0;
349             # global field color codes in a hash of arrays
350             my %_fielclrz = (
351             'simp' => ['!r', # DarkRed Century
352             '!R', # Red Year
353             '!O', # Orange Month
354             '!Y', # Yellow Day
355             '!G', # Green hour
356             '!C', # Cyan minute
357             '!U', # Blue second
358             '!P', # Purple frame
359             '!p', # DarkPurple jink
360             '!w'], # Grey zone
361             'html' => ['7F0B1B', # DarkRed Century
362             'FF1B2B', # Red Year
363             'FF7B2B', # Orange Month
364             'FFFF1B', # Yellow Day
365             '1BFF3B', # Green hour
366             '1BFFFF', # Cyan minute
367             '1B7BFF', # Blue second
368             'BB1BFF', # Purple frame
369             '5B0B7F', # DarkPurple jink
370             '7F7F7F'], # Grey zone
371             'ansi' => ["\e[0;31m", # DarkRed Century
372             "\e[1;31m", # Red Year
373             "\e[0;33m", # Orange Month
374             "\e[1;33m", # Yellow Day
375             "\e[1;32m", # Green hour
376             "\e[1;36m", # Cyan minute
377             "\e[1;34m", # Blue second
378             "\e[1;35m", # Purple frame
379             "\e[0;35m", # DarkPurple jink
380             "\e[0;30m"], # Grey zone
381             '4nt' => ["04", # DarkRed Century
382             "0c", # Red Year
383             "06", # Orange Month
384             "0e", # Yellow Day
385             "0a", # Green hour
386             "0b", # Cyan minute
387             "09", # Blue second
388             "0d", # Purple frame
389             "05", # DarkPurple jink
390             "07"], # Grey zone
391             );
392              
393             # methods
394 264     264   443 sub _default_value { my ($self, $attr) = @_; $_attrdata{$attr}; } # Dflt vals
  264         873  
395 3036     3036   3962 sub _attribute_match { my ($self, $attr) = @_; $_attrmtch{$attr}; } # matching
  3036         5852  
396 164     164   889 sub _attribute_names { @_attrnamz; } # attribute names
397 0     0   0 sub _Time_Local { $locl; } # can Time::Local be used?
398 0     0   0 sub _Time_HiRes { $hirs; } # can Time::HiRes be used?
399             #sub _Curses_Simp { $simp; } # can Curses::Simp be used?
400              
401             # Time::Fields object constructor as class method or copy as object method.
402             # First param can be ref to copy. Not including optional ref from
403             # copy, default is no params to create a new empty Fields object.
404             # If params are supplied, they must be a single key && a single value.
405             # The key must be one of the following 3 types of constructor
406             # initialization mechanisms:
407             # 0) 'str' => (eg. 'str' => '0123456789')
408             # 1) 'list' => (eg. 'list' => [0, 1, 2..9])
409             # 2) 'hash' => (eg. 'hash' => {'jink' => 8})
410             sub new {
411 7     7 1 21 my ($nvkr, $ityp, $idat) = @_;
412 7         16 my $nobj = ref($nvkr);
413 7         15 my $clas = $ityp;
414 7 50 0     53 $clas = $nobj || $nvkr if(!defined($ityp) || $ityp !~ /::/);
      33        
415 7         29 my $self = bless({}, $clas);
416 7         32 foreach my $attr ( $self->_attribute_names() ) {
417 154         310 $self->{$attr} = $self->_default_value($attr); # init defaults
418 154 50       345 $self->{$attr} = $nvkr->{$attr} if($nobj); # && copy if supposed to
419             }
420             # there were init params with no colon (classname)
421 7 50 33     69 if(defined($ityp) && $ityp !~ /::/) {
422 0 0       0 ($ityp, $idat) = ('str', $ityp) unless(defined($idat));
423 0         0 foreach my $attr ( $self->_attribute_names() ) {
424 0 0       0 if ($ityp =~ /^s/i) { # 'str'
    0          
    0          
425 0 0       0 $self->{$attr} = b10($1) if($idat =~ s/^(.)//); # break down string
426             } elsif($ityp =~ /^[la]/i) { # 'list' or 'array'
427 0 0       0 $self->{$attr} = shift( @{$idat} ) if(@{$idat}); # shift list vals
  0         0  
  0         0  
428             } elsif($ityp =~ /^h/i) { # 'hash'
429             # do some searching to find hash key that matches
430 0         0 foreach(keys(%{$idat})) {
  0         0  
431 0 0       0 if($attr =~ /$_/) {
432 0         0 $self->{$attr} = $idat->{$_};
433 0         0 delete($idat->{$_});
434             }
435             }
436             } else { # undetected init type
437 0         0 croak "!*EROR*! Time::Fields::new initialization type: $ityp did not match 'str', 'list', or 'hash'!\n";
438             }
439             }
440             }
441 7         25 return($self);
442             }
443              
444             sub _field_colors { # return the color code array associated with a type
445 0     0   0 my $self = shift; my $type = shift;
  0         0  
446 0 0 0     0 $type = 'ansi' unless(defined($type) && exists($_fielclrz{lc($type)}));
447 0         0 return($_fielclrz{ lc($type) });
448             }
449              
450             sub _color_fields { # return a color string for a Fields object
451 0     0   0 my $self = shift;
452 0 0 0     0 my $fstr = shift || ' ' x 10; $fstr =~ s/0+$// if(length($fstr) <= 7);
  0         0  
453 0   0     0 my $ctyp = shift || 'ansi';
454 0         0 my @clrz = (); my $coun = 0; my $rstr = '';
  0         0  
  0         0  
455 0 0       0 if ($ctyp =~ /^s/i) { # simp color codes
    0          
456 0         0 @clrz = @{$self->_field_colors('simp')};
  0         0  
457 0 0       0 if(length($fstr) > 7) {
458 0         0 while(length($fstr) > $coun) { $rstr .= $clrz[$coun++]; }
  0         0  
459             } else {
460 0         0 while(length($fstr) > $coun) { $rstr .= $clrz[(1 + $coun++)]; }
  0         0  
461             }
462             } elsif($ctyp =~ /^h/i) { # HTML link && font color tag delimiters
463 0         0 @clrz = @{$self->_field_colors('html')};
  0         0  
464 0         0 $_ = '' foreach(@clrz);
465 0         0 $rstr = '';
466 0 0       0 if(length($fstr) > 7) {
467 0         0 while(length($fstr) > $coun) { $rstr .= $clrz[$coun] . substr($fstr, $coun++, 1) . ''; }
  0         0  
468             } else {
469 0         0 while(length($fstr) > $coun) { $rstr .= $clrz[(1 + $coun)] . substr($fstr, $coun++, 1) . ''; }
  0         0  
470             }
471 0         0 $rstr .= '';
472             } else { # ANSI escapes
473 0         0 @clrz = @{$self->_field_colors('ansi')};
  0         0  
474 0 0       0 if($ctyp =~ /^z/i) { # zsh prompt needs delimited %{ ANSI %}
475 0         0 for(my $i=0; $i<@clrz; $i++) { $clrz[$i] = '%{' . $clrz[$i] . '%}'; }
  0         0  
476             }
477 0 0       0 if(length($fstr) > 7) {
478 0         0 while(length($fstr) > $coun) { $rstr .= $clrz[$coun] . substr($fstr, $coun++, 1); }
  0         0  
479             } else {
480 0         0 while(length($fstr) > $coun) { $rstr .= $clrz[(1 + $coun)] . substr($fstr, $coun++, 1); }
  0         0  
481             }
482             }
483 0         0 return($rstr);
484             }
485              
486             sub color { # generic self color method to call overloaded subclass colorfields
487 0     0 0 0 my $self = shift;
488 0         0 my $fstr = "$self";
489 0   0     0 my $ctyp = shift || 'ansi';
490 0         0 return($self->_color_fields($fstr, $ctyp));
491             }
492              
493             sub AUTOLOAD { # methods (created as necessary)
494 1     1   9 no strict 'refs';
  1         2  
  1         1529  
495 8     8   415 my ($self, $nwvl) = @_;
496              
497             # normal set_/get_ methods
498 8 100       394 if ($AUTOLOAD =~ /.*::[sg]et(_\w+)/i) {
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    100          
    50          
499 3         13 my $atnm = lc($1);
500 3 0   0   17 *{$AUTOLOAD} = sub { $_[0]->{$atnm} = $_[1] if(@_ > 1); return($_[0]->{$atnm}); };
  3         16  
  0         0  
  0         0  
501 3 100       90 $self->{$atnm} = $nwvl if(@_ > 1);
502 3         225 return($self->{$atnm});
503             # use_??? to set/get field filters
504             } elsif($AUTOLOAD =~ /.*::(use_\w+)/i) {
505 0         0 my $atnm = '__' . lc($1);
506 0 0   0   0 *{$AUTOLOAD} = sub { $_[0]->{$atnm} = $_[1] if(@_ > 1); return($_[0]->{$atnm}); };
  0         0  
  0         0  
  0         0  
507 0 0       0 $self->{$atnm} = $nwvl if(@_ > 1);
508 0         0 return($self->{$atnm});
509             # Alias methods which must be detected before sweeps
510             } elsif($AUTOLOAD =~ /.*::time$/i) {
511 0     0   0 *{$AUTOLOAD} = sub { return($self->hms()); };
  0         0  
  0         0  
512 0         0 return($self->hms());
513             } elsif($AUTOLOAD =~ /.*::alltime$/i) {
514 0     0   0 *{$AUTOLOAD} = sub { return($self->hmsfjz()); };
  0         0  
  0         0  
515 0         0 return($self->hmsfjz());
516             } elsif($AUTOLOAD =~ /.*::date$/i) {
517 0     0   0 *{$AUTOLOAD} = sub { return($self->YMD()); };
  0         0  
  0         0  
518 0         0 return($self->YMD());
519             } elsif($AUTOLOAD =~ /.*::alldate$/i) {
520 0     0   0 *{$AUTOLOAD} = sub { return($self->CYMD()); };
  0         0  
  0         0  
521 0         0 return($self->CYMD());
522             } elsif($AUTOLOAD =~ /.*::all$/i) {
523 0     0   0 *{$AUTOLOAD} = sub { return($self->CYMDhmsfjz()); };
  0         0  
  0         0  
524 0         0 return($self->CYMDhmsfjz());
525             } elsif($AUTOLOAD =~ /.*::dt$/i) {
526 0     0   0 *{$AUTOLOAD} = sub { return($self->CYMDhmsfjz()); };
  0         0  
  0         0  
527 0         0 return($self->CYMDhmsfjz());
528 0         0 } elsif($AUTOLOAD =~ /.*::mday$/i) { my $atnm = '_day';
529 0 0   0   0 *{$AUTOLOAD} = sub { $_[0]->{$atnm} = $_[1] if(@_ > 1); return($_[0]->{$atnm}); };
  0         0  
  0         0  
  0         0  
530 0 0       0 $self->{$atnm} = $nwvl if(@_ > 1); return($self->{$atnm});
  0         0  
531             # all joint field methods (eg. YMD(), hms(), foo(), etc.
532             } elsif($AUTOLOAD =~ /.*::([CYMODhmisfjz][CYMODhmisfjz]+)$/i) {
533 3         30 my @fldl = split(//, $1);
534 3         8 my ($self, @nval) = @_; my @rval = (); my $atnm = ''; my $rgex;
  3         7  
  3         7  
  3         3  
535             # handle Month / minute exceptions
536 3         14 for(my $i=0; $i<$#fldl; $i++) {
537 20 100 100     73 $fldl[$i + 1] = 'O' if($fldl[$i] =~ /[yd]/i && $fldl[$i + 1] eq 'm');
538 20 50 66     56 $fldl[$i ] = 'O' if($fldl[$i] eq 'm' && $fldl[$i + 1] =~ /[yd]/i);
539 20 100       55 $fldl[$i ] = 'O' if($fldl[$i] eq 'M');
540 20 100       64 $fldl[$i ] = 'i' if($fldl[$i] eq 'm');
541             }
542 3         16 *{$AUTOLOAD} = sub {
543 12     12   131 my ($self, @nval) = @_; my @rval = ();
  12         22  
544 12         64 for(my $i=0; $i<@fldl; $i++) {
545 113         261 foreach my $attr ($self->_attribute_names()){
546 2486         4764 my $mtch = $self->_attribute_match($attr);
547 2486 100 100     19020 if(defined($mtch) && $fldl[$i] =~ /^$mtch/i) {
548 113 100       335 $self->{$attr} = $nval[$i] if($i < @nval);
549 113         389 push(@rval, $self->{$attr});
550             }
551             }
552             }
553 12         87 return(@rval);
554 3         43 };
555 3         11 for(my $i=0; $i<@fldl; $i++) {
556 23         49 foreach my $attr ($self->_attribute_names()){
557 506         932 my $mtch = $self->_attribute_match($attr);
558 506 100 100     3299 if(defined($mtch) && $fldl[$i] =~ /$mtch/i) {
559 23 100       143 $self->{$attr} = $nval[$i] if($i < @nval);
560 23         241 push(@rval, $self->{$attr});
561             }
562             }
563             }
564 3         27 return(@rval);
565             # sweeping matches to handle partial keys
566             } elsif($AUTOLOAD =~ /.*::[-_]?([CYMODhmisfjz])(.)?/i) {
567 2         9 my ($atl1, $atl2) = ($1, $2); my $atnm;
  2         5  
568 2 0 33     10 $atl1 = 'O' if($atl1 eq 'm' && defined($atl2) && lc($atl2) eq 'o');
      33        
569 2 0 33     8 $atl1 = 'i' if($atl1 eq 'M' && defined($atl2) && lc($atl2) eq 'i');
      33        
570 2 50       8 $atl1 = 'O' if($atl1 eq 'M');
571 2 50       7 $atl1 = 'i' if($atl1 eq 'm');
572 2         7 foreach my $attr ($self->_attribute_names()){
573 44         80 my $mtch = $self->_attribute_match($attr);
574 44 100 100     289 $atnm = $attr if(defined($mtch) && $atl1 =~ /$mtch/i);
575             }
576 2 50       9 if($atl1 eq 'O') {
577 0 0       0 if($AUTOLOAD =~ /.*::_/) { # 0-based month
578 0 0   0   0 *{$AUTOLOAD} = sub { $_[0]->{$atnm} = ($_[1] + 1) if(@_ > 1); return($_[0]->{$atnm} - 1); };
  0         0  
  0         0  
  0         0  
579 0 0       0 $self->{$atnm} = ($nwvl + 1) if(@_ > 1);
580 0         0 return($self->{$atnm} - 1);
581             }
582             }
583 2 0   0   19 *{$AUTOLOAD} = sub { $_[0]->{$atnm} = $_[1] if(@_ > 1); return($_[0]->{$atnm}); };
  2         9  
  0         0  
  0         0  
584 2 100       107 $self->{$atnm} = $nwvl if(@_ > 1);
585 2         92 return($self->{$atnm});
586             } else {
587 0           croak "No such method: $AUTOLOAD\n";
588             }
589             }
590              
591 0     0     sub DESTROY { } # do nothing but define in case && to calm warning in test.pl
592              
593             127;