| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#=============================== ISODate.pm ================================== |
|
2
|
|
|
|
|
|
|
# Filename: ISODate.pm |
|
3
|
|
|
|
|
|
|
# Description: ISO date handling. |
|
4
|
|
|
|
|
|
|
# Original Author: Dale M. Amon |
|
5
|
|
|
|
|
|
|
# Revised by: $Author: amon $ |
|
6
|
|
|
|
|
|
|
# Date: $Date: 2008-08-28 23:14:03 $ |
|
7
|
|
|
|
|
|
|
# Version: $Revision: 1.8 $ |
|
8
|
|
|
|
|
|
|
# License: LGPL 2.1, Perl Artistic or BSD |
|
9
|
|
|
|
|
|
|
# |
|
10
|
|
|
|
|
|
|
#============================================================================= |
|
11
|
1
|
|
|
1
|
|
1147
|
use strict; |
|
|
1
|
|
|
|
|
11
|
|
|
|
1
|
|
|
|
|
53
|
|
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
package DMA::ISODate; |
|
14
|
1
|
|
|
1
|
|
5
|
use vars qw{@ISA}; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
63
|
|
|
15
|
|
|
|
|
|
|
@ISA = qw( UNIVERSAL ); |
|
16
|
|
|
|
|
|
|
|
|
17
|
1
|
|
|
1
|
|
1112
|
use POSIX; |
|
|
1
|
|
|
|
|
11873
|
|
|
|
1
|
|
|
|
|
7
|
|
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
#============================================================================= |
|
20
|
|
|
|
|
|
|
# Class Methods |
|
21
|
|
|
|
|
|
|
#============================================================================= |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
sub new { |
|
24
|
0
|
|
|
0
|
1
|
|
my ($class, $datestring) = @_; |
|
25
|
0
|
|
|
|
|
|
return ($class->_new (0,$datestring)); |
|
26
|
|
|
|
|
|
|
} |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
sub unix { |
|
31
|
0
|
|
|
0
|
1
|
|
my ($class, $time,$utcflg) = @_; |
|
32
|
0
|
|
|
|
|
|
my $self = bless {}, $class; |
|
33
|
|
|
|
|
|
|
|
|
34
|
0
|
0
|
|
|
|
|
defined $time || (return undef); |
|
35
|
0
|
0
|
|
|
|
|
defined $utcflg || ($utcflg = 0); |
|
36
|
|
|
|
|
|
|
|
|
37
|
0
|
|
|
|
|
|
my($havedate,$havetime,$y2k) = (1,1,0); |
|
38
|
0
|
0
|
|
|
|
|
my ($sec,$min,$hr,$day,$mon,$yr) = |
|
39
|
|
|
|
|
|
|
($utcflg) ? gmtime($time) : localtime ($time); |
|
40
|
0
|
|
|
|
|
|
$yr+=1900; $mon+=1; |
|
|
0
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
|
|
42
|
0
|
|
|
|
|
|
@$self{'y2k','havetime','isUTC', |
|
43
|
|
|
|
|
|
|
'yr','mon','day','hr','min','sec'} = |
|
44
|
|
|
|
|
|
|
($y2k,$havetime,$utcflg, |
|
45
|
|
|
|
|
|
|
$yr,$mon,$day,$hr,$min,$sec); |
|
46
|
|
|
|
|
|
|
|
|
47
|
0
|
|
|
|
|
|
$self->_set_iso_strings; |
|
48
|
0
|
|
|
|
|
|
return $self; |
|
49
|
|
|
|
|
|
|
} |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
52
|
|
|
|
|
|
|
|
|
53
|
0
|
|
|
0
|
1
|
|
sub now {return (shift->_new (0,undef));} |
|
54
|
0
|
|
|
0
|
1
|
|
sub utc {return (shift->_new (1,undef));} |
|
55
|
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
57
|
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub new_formatted { |
|
59
|
0
|
|
|
0
|
1
|
|
my ($class,$fmt,$string) = @_; |
|
60
|
0
|
|
|
|
|
|
my $self = bless {}, $class; |
|
61
|
|
|
|
|
|
|
|
|
62
|
0
|
|
|
|
|
|
return $self; |
|
63
|
|
|
|
|
|
|
} |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
#============================================================================= |
|
66
|
|
|
|
|
|
|
# Object Methods |
|
67
|
|
|
|
|
|
|
#============================================================================= |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
sub get { |
|
70
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
71
|
0
|
0
|
|
|
|
|
return $self->{'date'} . (($self->{'havetime'}) ? $self->{'time'} : "");} |
|
72
|
|
|
|
|
|
|
|
|
73
|
0
|
|
|
0
|
1
|
|
sub canonical {my ($self) = @_; return $self->{'date'} . $self->{'time'};} |
|
|
0
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
76
|
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub yearly { |
|
78
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
79
|
0
|
|
|
|
|
|
@$self{'mon','day','hr','min','sec','havetime'} = (0,0,0,0,0,0); |
|
80
|
0
|
|
|
|
|
|
$self->_set_iso_strings; |
|
81
|
0
|
|
|
|
|
|
return $self; |
|
82
|
|
|
|
|
|
|
} |
|
83
|
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub monthly { |
|
85
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
86
|
0
|
|
|
|
|
|
@$self{'day','hr','min','sec','havetime'} = (0,0,0,0,0); |
|
87
|
0
|
|
|
|
|
|
$self->_set_iso_strings; |
|
88
|
0
|
|
|
|
|
|
return $self; |
|
89
|
|
|
|
|
|
|
} |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
92
|
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
sub isyearly { |
|
94
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
95
|
0
|
0
|
|
|
|
|
return (($self->{'mon'} + $self->{'day'} + $self->{'havetime'}) ? 0 : 1); |
|
96
|
|
|
|
|
|
|
} |
|
97
|
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub ismonthly { |
|
99
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
100
|
0
|
0
|
|
|
|
|
return (($self->{'day'} + $self->{'havetime'}) ? 0 : 1); |
|
101
|
|
|
|
|
|
|
} |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
104
|
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
my @Q = ("Q1-Q4", |
|
106
|
|
|
|
|
|
|
"Q1", "Q1", "Q1", |
|
107
|
|
|
|
|
|
|
"Q2", "Q2", "Q2", |
|
108
|
|
|
|
|
|
|
"Q3", "Q3", "Q3", |
|
109
|
|
|
|
|
|
|
"Q4", "Q4", "Q4"); |
|
110
|
|
|
|
|
|
|
|
|
111
|
0
|
|
|
0
|
1
|
|
sub quarter {return $Q[shift->{'month'}];} |
|
112
|
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
114
|
|
|
|
|
|
|
|
|
115
|
0
|
|
|
0
|
1
|
|
sub date {return shift->{'date'};} |
|
116
|
0
|
|
|
0
|
1
|
|
sub time {return shift->{'time'};} |
|
117
|
0
|
|
|
0
|
1
|
|
sub y2k {return shift->{'y2k'};} |
|
118
|
0
|
|
|
0
|
1
|
|
sub havetime {return shift->{'havetime'};} |
|
119
|
0
|
|
|
0
|
1
|
|
sub isUTC {return shift->{'isUTC'};} |
|
120
|
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
122
|
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
sub timearray { |
|
124
|
0
|
|
|
0
|
1
|
|
my ($self) = @_; |
|
125
|
0
|
|
|
|
|
|
return (@$self{'yr','mon','day','hr','min','sec', |
|
126
|
|
|
|
|
|
|
'havetime','isUTC','y2k'}); |
|
127
|
|
|
|
|
|
|
} |
|
128
|
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
#============================================================================= |
|
130
|
|
|
|
|
|
|
# Internal Methods |
|
131
|
|
|
|
|
|
|
#============================================================================= |
|
132
|
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub _new { |
|
134
|
0
|
|
|
0
|
|
|
my ($class, $utcflg,$str) = @_; |
|
135
|
0
|
|
|
|
|
|
my $self = bless {}, $class; |
|
136
|
|
|
|
|
|
|
|
|
137
|
0
|
|
|
|
|
|
my ($havedate,$havetime,$y2k, |
|
138
|
|
|
|
|
|
|
$yr,$mon,$day,$hr,$min,$sec) = |
|
139
|
|
|
|
|
|
|
(0,0,0, |
|
140
|
|
|
|
|
|
|
0,0,0,0,0,0); |
|
141
|
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# Times come back in 2-3 digit format which we treat as a y2k correction. |
|
143
|
0
|
0
|
|
|
|
|
if (!defined $str) { |
|
144
|
0
|
|
|
|
|
|
($havedate,$havetime,$y2k) = (1,1,0); |
|
145
|
0
|
0
|
|
|
|
|
($sec,$min,$hr,$day,$mon,$yr) = |
|
146
|
|
|
|
|
|
|
($utcflg) ? gmtime(CORE::time) : localtime (CORE::time); |
|
147
|
0
|
|
|
|
|
|
$yr+=1900; $mon+=1; |
|
|
0
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
} |
|
149
|
|
|
|
|
|
|
else { |
|
150
|
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
# Try ISO date format first. |
|
152
|
|
|
|
|
|
|
# ***** THESE VALUES ARE NOT CHECKED FOR LIMITS OR THAT THE DAY OF THE |
|
153
|
|
|
|
|
|
|
# MONTH EXISTS IN THAT MONTH AND YEAR. |
|
154
|
0
|
|
|
|
|
|
($havedate,$havetime,$y2k, |
|
155
|
|
|
|
|
|
|
$yr,$mon,$day,$hr,$min,$sec) = $self->_isodate($str); |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
# ***** Later on fill this in so it handles other formats. |
|
158
|
0
|
0
|
|
|
|
|
if (!$havedate) {return undef;} |
|
|
0
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
} |
|
160
|
|
|
|
|
|
|
|
|
161
|
0
|
0
|
|
|
|
|
$havedate || return undef; |
|
162
|
|
|
|
|
|
|
|
|
163
|
0
|
|
|
|
|
|
@$self{'y2k','havetime','isUTC', |
|
164
|
|
|
|
|
|
|
'yr','mon','day','hr','min','sec'} = |
|
165
|
|
|
|
|
|
|
($y2k,$havetime,$utcflg, |
|
166
|
|
|
|
|
|
|
$yr,$mon,$day,$hr,$min,$sec); |
|
167
|
|
|
|
|
|
|
|
|
168
|
0
|
|
|
|
|
|
$self->_set_iso_strings; |
|
169
|
0
|
|
|
|
|
|
return $self; |
|
170
|
|
|
|
|
|
|
} |
|
171
|
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
173
|
|
|
|
|
|
|
# See if we can make an ISODATE out of the string with no chars left over. |
|
174
|
|
|
|
|
|
|
# An ISODATE must be at least 6 digits long; it may be for 1 Million AD, |
|
175
|
|
|
|
|
|
|
# so we allow lots of digits. Of course you can't stuff that in a Unix |
|
176
|
|
|
|
|
|
|
# timval, but we don't need to anyway. |
|
177
|
|
|
|
|
|
|
# |
|
178
|
|
|
|
|
|
|
# The return values are in a canonical form: |
|
179
|
|
|
|
|
|
|
# havedate => true if we found the date |
|
180
|
|
|
|
|
|
|
# havetime => true if we found the time |
|
181
|
|
|
|
|
|
|
# y2k => true if we had a 2 digit year on input. |
|
182
|
|
|
|
|
|
|
# |
|
183
|
|
|
|
|
|
|
# We could get fancier if we had to. It would not be hard to deal with |
|
184
|
|
|
|
|
|
|
# ISO time and date seperated by delimiters; we could also check potential |
|
185
|
|
|
|
|
|
|
# MM,DD,YY,HH, MM, SS for validity if we needed to. We will let the caller |
|
186
|
|
|
|
|
|
|
# use a standard Perl Module of some sort for that job rather than redoing |
|
187
|
|
|
|
|
|
|
# it. We just assume that if it looks ISODATE and is not, it was wrong |
|
188
|
|
|
|
|
|
|
# and could not have been parsed in an alternative format. Until someone |
|
189
|
|
|
|
|
|
|
# points out an exception, that's my story and I'm sticking to it. |
|
190
|
|
|
|
|
|
|
# |
|
191
|
|
|
|
|
|
|
# I am leaving extra conditionals here as hooks for in case I was wrong. |
|
192
|
|
|
|
|
|
|
# Otherwise I could simplify the routine by a number of lines. Likewise, |
|
193
|
|
|
|
|
|
|
# |
|
194
|
|
|
|
|
|
|
# ASSUME: I assume two or three digit years should always be replaced |
|
195
|
|
|
|
|
|
|
# by yr+1900. Two digit is assumed to be a Y2K problem; 3 digit |
|
196
|
|
|
|
|
|
|
# is assumed to be a Unix timval that really is yr-1900. Perhaps |
|
197
|
|
|
|
|
|
|
# we'll need a U2K for 2038... |
|
198
|
|
|
|
|
|
|
# |
|
199
|
|
|
|
|
|
|
# ASSUME: There is no such thing as an ISODATE that only has the time |
|
200
|
|
|
|
|
|
|
# portion HHMMSS. |
|
201
|
|
|
|
|
|
|
# |
|
202
|
|
|
|
|
|
|
# Args: self |
|
203
|
|
|
|
|
|
|
# string |
|
204
|
|
|
|
|
|
|
# Returns: (havedate, havetime, y2k, |
|
205
|
|
|
|
|
|
|
# year, month, day, hour, minute, second, |
|
206
|
|
|
|
|
|
|
# remaining_chars) |
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
sub _isodate { |
|
209
|
0
|
|
|
0
|
|
|
my ($self, $str) = @_; |
|
210
|
0
|
|
|
|
|
|
my $r = $str; |
|
211
|
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
# See if we've got a possible ISO date, at least 6 chars. |
|
213
|
0
|
0
|
|
|
|
|
if ($str =~ /^(\d{6,})$/) { |
|
214
|
0
|
|
|
|
|
|
my ($a1,$a2,$a3,$b1,$b2,$b3,$b4,$b5,$b6); |
|
215
|
0
|
|
|
|
|
|
my ($iso, $len) = ($1, length $1); |
|
216
|
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
# The 3 item (minimum 6 digits) parse |
|
218
|
0
|
0
|
|
|
|
|
if ($iso =~ /^(\d{2,})(\d\d)(\d\d)(.*)/) {($a1,$a2,$a3,$r) = ($1,$2,$3,$4);} |
|
|
0
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
# The 6 item (minimum 12 digits) parse |
|
221
|
0
|
0
|
0
|
|
|
|
if (($len > 6) && |
|
222
|
|
|
|
|
|
|
($iso =~ /^(\d{2,})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(.*)$/)) { |
|
223
|
0
|
|
|
|
|
|
($b1,$b2,$b3,$b4,$b5,$b6,$r) = ($1,$2,$3,$4,$5,$6,$7);} |
|
224
|
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
# 3 item: YYMMDD; (or HHMMSS if we allowed that). This is a Y2K. |
|
226
|
0
|
0
|
|
|
|
|
if ($len == 6) {return (1,0,1, $a1+1900,$a2,$a3, 0,0,0, $r);} |
|
|
0
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
# 3 item: YYYMMDD, probably a Unix year after 1900. Not a y2k. |
|
229
|
0
|
0
|
|
|
|
|
if ($len == 7) {return (1,0,0, $a1+1900,$a2,$a3, 0,0,0, $r);} |
|
|
0
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
# 3 item: YYYYMMDD to YYYYYYYYMMDD, the later being rather unlikely |
|
232
|
0
|
0
|
0
|
|
|
|
if (($len >= 8) && ($len < 12)) {return (1,0,0, $a1,$a2,$a3, 0,0,0, $r);} |
|
|
0
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
# 6 item: YYMMDDHHMMSS, a y2k date or 3 item: YYYYYYYYMMDD, the later |
|
235
|
|
|
|
|
|
|
# being rather unlikely but an annoying loss. |
|
236
|
0
|
0
|
|
|
|
|
if ($len == 12) {return (1,1,1, $b1+1900,$b2,$b3, $b4,$b5,$b6, $r);} |
|
|
0
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
# YYYMMDDHHMMSS or YYYYYYYYYYMMDD, the first being a format error |
|
239
|
|
|
|
|
|
|
# with a Unix year after 1900 but more likely than the later. |
|
240
|
0
|
0
|
|
|
|
|
if ($len == 13) {return (1,1,0, $b1+1900,$b2,$b3, $b4,$b5,$b6, $r);} |
|
|
0
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
# YYYYMMDDHHMMSS to {Y...}YYYYMMDDHHMMSS to infinity and beyond... |
|
243
|
0
|
|
|
|
|
|
return (1,1,0, $b1,$b2,$b3, $b4,$b5,$b6, $r); |
|
244
|
|
|
|
|
|
|
} |
|
245
|
0
|
|
|
|
|
|
return (0,0,0, 0,0,0, 0,0,0, $r); |
|
246
|
|
|
|
|
|
|
} |
|
247
|
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
|
249
|
|
|
|
|
|
|
# Update the date and time strings from the yr,mon,day,hr,min,sec fields. |
|
250
|
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
sub _set_iso_strings { |
|
252
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
|
253
|
0
|
|
|
|
|
|
@$self{'date','time','havetime'} = |
|
254
|
|
|
|
|
|
|
(sprintf ("%04d%02d%02d", @$self{'yr','mon','day'}), |
|
255
|
|
|
|
|
|
|
sprintf ("%02d%02d%02d", @$self{'hr','min','sec'}), |
|
256
|
|
|
|
|
|
|
$self->{'havetime'}); |
|
257
|
0
|
|
|
|
|
|
return $self; |
|
258
|
|
|
|
|
|
|
} |
|
259
|
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
#============================================================================= |
|
261
|
|
|
|
|
|
|
# Pod Documentation |
|
262
|
|
|
|
|
|
|
#============================================================================= |
|
263
|
|
|
|
|
|
|
# You may extract and format the documentation section with the 'perldoc' cmd. |
|
264
|
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
=head1 NAME |
|
266
|
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
DMA::ISODate.pm - ISO date handling. |
|
268
|
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
270
|
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
use DMA::ISODate; |
|
272
|
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
$obj = DMA::ISOdate->new ($datestring); |
|
274
|
|
|
|
|
|
|
$obj = DMA::ISOdate->now; |
|
275
|
|
|
|
|
|
|
$obj = DMA::ISOdate->utc; |
|
276
|
|
|
|
|
|
|
$obj = DMA::ISOdate->unix ($time, $gmflag); |
|
277
|
|
|
|
|
|
|
$obj = DMA::ISOdate->new_formatted ($fmt, $string); |
|
278
|
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
$datestring = $obj->get; |
|
280
|
|
|
|
|
|
|
$datestring = $obj->canonical; |
|
281
|
|
|
|
|
|
|
$obj = $obj->yearly; |
|
282
|
|
|
|
|
|
|
$obj = $obj->monthly; |
|
283
|
|
|
|
|
|
|
$obj = $obj->isyearly; |
|
284
|
|
|
|
|
|
|
$obj = $obj->ismonthly; |
|
285
|
|
|
|
|
|
|
$quarter = $obj->quarter; |
|
286
|
|
|
|
|
|
|
$season = $obj->season; |
|
287
|
|
|
|
|
|
|
$datestring = $obj->date; |
|
288
|
|
|
|
|
|
|
$timestring = $obj->time; |
|
289
|
|
|
|
|
|
|
$havetime = $obj->havetime; |
|
290
|
|
|
|
|
|
|
$y2k = $obj->y2k; |
|
291
|
|
|
|
|
|
|
$utc = $obj->isUTC; |
|
292
|
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
($yr,$mon,$day,$hr,$min,$sec,$havetime,$utc,$y2k) = $obj->timearray; |
|
294
|
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=head1 Inheritance |
|
296
|
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
UNIVERSAL |
|
298
|
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
=head1 Description |
|
300
|
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
The primary date time we use is the ISO date, almost always in the basic |
|
302
|
|
|
|
|
|
|
form of YYYYMMDD , like 20021209, but the DMA::ISOdate class will attempt to |
|
303
|
|
|
|
|
|
|
create an ISODate from what ever you give it: |
|
304
|
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
Input data Canonical ISO result |
|
306
|
|
|
|
|
|
|
YYMMDD => 19YYMMDD000000 |
|
307
|
|
|
|
|
|
|
YYYMMDD => (1900+YYY)MMDD000000 |
|
308
|
|
|
|
|
|
|
YYYYMMDD => YYYYMMDD000000 |
|
309
|
|
|
|
|
|
|
YYYYYMMDD => YYYYYMMDD000000 |
|
310
|
|
|
|
|
|
|
YYYYYYMMDD => YYYYYYMMDD000000 |
|
311
|
|
|
|
|
|
|
YYYYYYYMMDD => YYYYYYYMMDD000000 |
|
312
|
|
|
|
|
|
|
YYMMDDHHMMSS => 19YYMMDDHHMMSS |
|
313
|
|
|
|
|
|
|
YYYMMDDHHMMSS => (1900+YY)MMDDHHMMSS |
|
314
|
|
|
|
|
|
|
YYYYMMDDHHMMSS => YYYYMMDDHHMMSS |
|
315
|
|
|
|
|
|
|
{Y..}YYYYMMDDHHMMSS => {Y..}YYYYMMDDHHMMSS |
|
316
|
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
Note that a minimum of 4 digits is needed to correctly express years like |
|
318
|
|
|
|
|
|
|
40AD so as to differentiate it from 1940AD which is what the Y2K correction |
|
319
|
|
|
|
|
|
|
would do with "401209". There are also problems: years cannot be expressed |
|
320
|
|
|
|
|
|
|
beyond 9999999 in the date only format. |
|
321
|
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
Two digit years (00-99) are assume to be Y2K legacy dates. We set the y2k |
|
323
|
|
|
|
|
|
|
flag and add 1900 to the year value when we see one. |
|
324
|
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
Three digit years (000-999) are likely to be uncorrected Unix date returns. |
|
326
|
|
|
|
|
|
|
We do not set the y2k but we do add 1900. This is safe until we hit what |
|
327
|
|
|
|
|
|
|
I'll call the "U2K" date of 2038 when Unix 32b int timevals roll over. This |
|
328
|
|
|
|
|
|
|
is not a problem for this Class; we follow the philosophy of "be liberal on |
|
329
|
|
|
|
|
|
|
inputs and conservative on outputs". |
|
330
|
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
If this all seems very ad hoc -- it is. Date formats are very ad hoc with |
|
332
|
|
|
|
|
|
|
ambiguities which can only be decided with contextual information. That's a |
|
333
|
|
|
|
|
|
|
job for people, not a poor wee ISODate Class. |
|
334
|
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
Four digit year formats are not limited to 4 digits. We can express dates far |
|
336
|
|
|
|
|
|
|
into the future. In any place hereafter where we use "YYYY", any number of |
|
337
|
|
|
|
|
|
|
extra digits are possible. |
|
338
|
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
[We aren't affected by the size of Unix timval (ie the 2038 max year) except |
|
340
|
|
|
|
|
|
|
it is not convenient right now to do a perpetual calendar of my own to check |
|
341
|
|
|
|
|
|
|
the validity of a date.] |
|
342
|
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
We do not, however, have any means of representing dates BC. For this we might |
|
344
|
|
|
|
|
|
|
consider using the Peter Kokh dating system which adds 10000 to the AD date to |
|
345
|
|
|
|
|
|
|
represent all of human history after the end of the most recent Ice Age. This |
|
346
|
|
|
|
|
|
|
allows much easier translation between all modern and ancient dating systems |
|
347
|
|
|
|
|
|
|
if you remember there was no year zero as they had not gotten around to |
|
348
|
|
|
|
|
|
|
inventing nothing back then. (Given some recent discoveries offshore in India, |
|
349
|
|
|
|
|
|
|
I might prefer adding 20000 years!) |
|
350
|
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
=head1 Examples |
|
352
|
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
None. |
|
354
|
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
=head1 Class Variables |
|
356
|
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
None. |
|
358
|
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
=head1 Instance Variables |
|
360
|
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
y2k Set if external input was in two digit year format, t/f. |
|
362
|
|
|
|
|
|
|
havetime Set if input included the time, t/f |
|
363
|
|
|
|
|
|
|
isUTC date/time is known to be UTC, t/f. |
|
364
|
|
|
|
|
|
|
(What should the default be since we will |
|
365
|
|
|
|
|
|
|
only know this if we got the time via newgm.) |
|
366
|
|
|
|
|
|
|
date "YYYYMMDD" |
|
367
|
|
|
|
|
|
|
time "HHMMSS", default is "000000" |
|
368
|
|
|
|
|
|
|
yr integer year, 0 -size of int |
|
369
|
|
|
|
|
|
|
mon integer month, 1-12,; 0=no month |
|
370
|
|
|
|
|
|
|
day integer day, 1-28,29,30 or 31; 0=no day |
|
371
|
|
|
|
|
|
|
hr integer hour, 0-23 |
|
372
|
|
|
|
|
|
|
min integer minute, 0-59 |
|
373
|
|
|
|
|
|
|
sec integer second, 0-59 |
|
374
|
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
=head1 Class Methods |
|
376
|
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
=over 4 |
|
378
|
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
=item B<$obj = DMA::ISOdate-Enew ($datestring)> |
|
380
|
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
Assume the $datestring is a local ISO date or date/time in one of the formats |
|
382
|
|
|
|
|
|
|
discussed earlier. Returns undef if $datestring can't be parsed our way; 1900 |
|
383
|
|
|
|
|
|
|
is added to the year if 2 or 3 digits are found and the y2k flag set for 2 |
|
384
|
|
|
|
|
|
|
digit years. havetime is set if there was an HHMMSS in the string. |
|
385
|
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
Returns a new object or undef on failure. |
|
387
|
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
=item B<$obj = DMA::ISOdate-Enew_formatted ($fmt, $string)> |
|
389
|
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
Use a Perl date format string to identify the date format we believe $string |
|
391
|
|
|
|
|
|
|
to be in. It returns undef instead of creating a new object if the date |
|
392
|
|
|
|
|
|
|
doesn't work in the given format. |
|
393
|
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
=item B<$obj = DMA::ISOdate-Enow> |
|
395
|
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
Create an object with the current time set to right now in local time. Always |
|
397
|
|
|
|
|
|
|
succeeds, always Y2K compliant and has HHMMSS available. |
|
398
|
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
=item B<$obj = DMA::ISOdate-Eunix ($time, $gmflag)> |
|
400
|
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
Create an object for a unix timeval. $time is required and assumed to be a |
|
402
|
|
|
|
|
|
|
unix time integer. If $gmflag is present and set, make it a UTC time, |
|
403
|
|
|
|
|
|
|
otherwise it is local time. Always succeeds, always Y2K compliant and has |
|
404
|
|
|
|
|
|
|
HHMMSS available. |
|
405
|
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
This routine is useful when dealing with info from archive file directory |
|
407
|
|
|
|
|
|
|
stats. |
|
408
|
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
=item B<$obj = DMA::ISOdate-Eutc> |
|
410
|
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
Create an object with the current time set to right now in UTC time. Always |
|
412
|
|
|
|
|
|
|
succeeds, always Y2K compliant and has HHMMSS available. |
|
413
|
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
=back 4 |
|
415
|
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
=head1 Instance Methods |
|
417
|
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
=over 4 |
|
419
|
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
=item B<$datestring = $obj-Ecanonical> |
|
421
|
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
Returns an the object's ISODATE. In a canonical form: YYYYMMDD HHMMSS . If |
|
423
|
|
|
|
|
|
|
havetime is not set, we get YYYYMMDD000000. |
|
424
|
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
=item B<$datestring = $obj-Edate> |
|
426
|
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
Returns the ISO date as YYYYMMDD . |
|
428
|
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
=item B<$datestring = $obj-Eget> |
|
430
|
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
Returns an the object's ISODATE. In one of two forms, either YYYYMMDD if |
|
432
|
|
|
|
|
|
|
havetime is not set or YYYYMMDDHHMMSS if it is. |
|
433
|
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
=item B<$havetime = $obj-Ehavetime> |
|
435
|
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
True if we have a time of day stored. |
|
437
|
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
=item B<$obj = $obj-Eismonthly> |
|
439
|
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
Test if the ISO date is suitable for things like monthly magazines. Returns |
|
441
|
|
|
|
|
|
|
true if havetime and day of month are clear. It means your ISO date is of the |
|
442
|
|
|
|
|
|
|
form "19950500". |
|
443
|
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
=item B<$utc = $obj-EisUTC> |
|
445
|
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
True if the time we stored was UTC. |
|
447
|
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
=item B<$obj = $obj-Eisyearly> |
|
449
|
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
Test if the ISO date is suitable for things like yearly reports. Returns true |
|
451
|
|
|
|
|
|
|
if havetime, month and day of month are clear. It means your ISO date is of |
|
452
|
|
|
|
|
|
|
the form "19950000". |
|
453
|
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
=item B<$obj = $obj-Emonthly> |
|
455
|
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
Change the ISO date so it is of use for things like monthly magazines. |
|
457
|
|
|
|
|
|
|
havetime is cleared. All time and date field below month are zeroed. Your |
|
458
|
|
|
|
|
|
|
ISO date will now look like "19950500". |
|
459
|
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
=item B<$quarter = $obj-Equarter> |
|
461
|
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
Returns the quarter string for the date. Q1,Q2,Q3,Q4 or Q1-Q4 if the date has |
|
463
|
|
|
|
|
|
|
no month, eg "19950000". |
|
464
|
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
=item B<$season = $obj-Eseason> |
|
466
|
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
Returns the season: winter, spring,summer,fall. |
|
468
|
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
=item B<$timestring = $obj-Etime> |
|
470
|
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
Returns the time as HHMMSS if havetime is set; otherwise the midnight time |
|
472
|
|
|
|
|
|
|
string "000000". |
|
473
|
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
=item B<($yr,$mon,$day,$hr,$min,$sec,$havetime,$utc,$y2k) = $obj-Etimearray> |
|
475
|
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
Return the date/time information. |
|
477
|
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
=item B<$y2k = $obj-Ey2k> |
|
479
|
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
True if we applied a Y2K correction to the year in our stored date. |
|
481
|
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
=item B<$obj = $obj-Eyearly> |
|
483
|
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
Change the ISO date so it is of use for things like yearly reports. havetime |
|
485
|
|
|
|
|
|
|
is cleared. All time and date field below year are zeroed. Your ISO date |
|
486
|
|
|
|
|
|
|
will now look like "19950000". |
|
487
|
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
=back 4 |
|
489
|
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
=head1 Private Class Methods |
|
491
|
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
=over 4 |
|
493
|
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
=item B<$obj = DMA::ISOdate-E_new ($type,$gmflag,$datestring)> |
|
495
|
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
Internal base initializer method which all the other initializer methods |
|
497
|
|
|
|
|
|
|
call. |
|
498
|
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
Not part of the advertised interface for this class, so don't try to use it |
|
500
|
|
|
|
|
|
|
directly. |
|
501
|
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
Returns self or undef if no date found/created. |
|
503
|
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
=back 4 |
|
505
|
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
=head1 Private Instance Methods |
|
507
|
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
None, although I may wish to include the code comments from _isodate here as |
|
509
|
|
|
|
|
|
|
it is quite extensive. |
|
510
|
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
=head1 KNOWN BUGS |
|
512
|
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
See TODO. |
|
514
|
|
|
|
|
|
|
|
|
515
|
|
|
|
|
|
|
=head1 SEE ALSO |
|
516
|
|
|
|
|
|
|
|
|
517
|
|
|
|
|
|
|
None. |
|
518
|
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
=head1 AUTHOR |
|
520
|
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
Dale Amon |
|
522
|
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
=cut |
|
524
|
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
#============================================================================= |
|
526
|
|
|
|
|
|
|
# CVS HISTORY |
|
527
|
|
|
|
|
|
|
#============================================================================= |
|
528
|
|
|
|
|
|
|
# $Log: ISODate.pm,v $ |
|
529
|
|
|
|
|
|
|
# Revision 1.8 2008-08-28 23:14:03 amon |
|
530
|
|
|
|
|
|
|
# perldoc section regularization. |
|
531
|
|
|
|
|
|
|
# |
|
532
|
|
|
|
|
|
|
# Revision 1.7 2008-08-15 21:47:52 amon |
|
533
|
|
|
|
|
|
|
# Misc documentation and format changes. |
|
534
|
|
|
|
|
|
|
# |
|
535
|
|
|
|
|
|
|
# Revision 1.6 2008-04-18 14:07:54 amon |
|
536
|
|
|
|
|
|
|
# Minor documentation format changes |
|
537
|
|
|
|
|
|
|
# |
|
538
|
|
|
|
|
|
|
# Revision 1.5 2008-04-11 22:25:23 amon |
|
539
|
|
|
|
|
|
|
# Add blank line after cut. |
|
540
|
|
|
|
|
|
|
# |
|
541
|
|
|
|
|
|
|
# Revision 1.4 2008-04-11 18:56:35 amon |
|
542
|
|
|
|
|
|
|
# Fixed quoting problem with formfeeds. |
|
543
|
|
|
|
|
|
|
# |
|
544
|
|
|
|
|
|
|
# Revision 1.3 2008-04-11 18:39:15 amon |
|
545
|
|
|
|
|
|
|
# Implimented new standard for headers and trailers. |
|
546
|
|
|
|
|
|
|
# |
|
547
|
|
|
|
|
|
|
# Revision 1.2 2008-04-10 15:01:08 amon |
|
548
|
|
|
|
|
|
|
# Added license to headers, removed claim that the documentation section still |
|
549
|
|
|
|
|
|
|
# relates to the old doc file. |
|
550
|
|
|
|
|
|
|
# |
|
551
|
|
|
|
|
|
|
# Revision 1.1.1.1 2004-09-19 21:59:12 amon |
|
552
|
|
|
|
|
|
|
# Dale's library of primitives in Perl |
|
553
|
|
|
|
|
|
|
# |
|
554
|
|
|
|
|
|
|
# 20040813 Dale Amon |
|
555
|
|
|
|
|
|
|
# Moved to DMA:: from Archivist:: |
|
556
|
|
|
|
|
|
|
# to make it easier to enforce layers. |
|
557
|
|
|
|
|
|
|
# |
|
558
|
|
|
|
|
|
|
# 20021207 Dale Amon |
|
559
|
|
|
|
|
|
|
# Created. |
|
560
|
|
|
|
|
|
|
1; |