Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | |
2 | =head1 NAME | |
3 | ||
4 | Date::Calc::Object - Object-oriented add-on for Date::Calc with overloaded operators | |
5 | ||
6 | =head1 MOTTO | |
7 | ||
8 | Make frequent things easy and infrequent or hard things possible | |
9 | ||
10 | =head1 PREFACE | |
11 | ||
12 | Note that you do B<NOT> need to "C<use Date::Calc qw(...);>" in | |
13 | addition to this module. | |
14 | ||
15 | Simply | |
16 | ||
17 | use Date::Calc::Object qw(...); | |
18 | ||
19 | B<INSTEAD OF> | |
20 | ||
21 | use Date::Calc qw(...); | |
22 | ||
23 | with the same "C<qw(...)>" as you would with the "Date::Calc" | |
24 | module, and then forget about "Date::Calc::Object" altogether. | |
25 | ||
26 | The rest of your existing code doesn't change at all. | |
27 | ||
28 | Note also that in order to create a new date object, you do not | |
29 | need to use | |
30 | ||
31 | $date_object = Date::Calc::Object->new(...); | |
32 | ||
33 | (but you may), and should use | |
34 | ||
35 | $date_object = Date::Calc->new(...); | |
36 | ||
37 | instead (saves you some typing and is a trifle faster). | |
38 | ||
39 | =head1 SYNOPSIS | |
40 | ||
41 | =head2 Export tags | |
42 | ||
43 | :all - all functions from Date::Calc | |
44 | :aux - auxiliary functions shift_* | |
45 | :ALL - both :all and :aux | |
46 | ||
47 | =head2 Functions | |
48 | ||
49 | See L<Date::Calc(3)> for a list of available functions. | |
50 | ||
51 | $year = shift_year(\@_); | |
52 | ($year,$mm,$dd) = shift_date(\@_); | |
53 | ($hrs,$min,$sec) = shift_time(\@_); | |
54 | ($year,$mm,$dd,$hrs,$min,$sec) = shift_datetime(\@_); | |
55 | ||
56 | =head2 Methods | |
57 | ||
58 | $old = Date::Calc->accurate_mode([FLAG]); | |
59 | $old = Date::Calc->number_format([NUMBER|CODEREF]); | |
60 | $old = Date::Calc->delta_format([NUMBER|CODEREF]); # global default | |
61 | $old = Date::Calc->date_format([NUMBER|CODEREF]); # global default | |
62 | $old = Date::Calc->language([LANGUAGE]); # global default | |
63 | ||
64 | $old = $date->accurate_mode([FLAG]); # is global nevertheless! | |
65 | $old = $date->number_format([NUMBER|CODEREF]); # is global nevertheless! | |
66 | $old = $date->delta_format([NUMBER|CODEREF]); # individual override | |
67 | $old = $date->date_format([NUMBER|CODEREF]); # individual override | |
68 | $old = $date->language([LANGUAGE]); # individual override | |
69 | ||
70 | $flag = $date->is_delta(); | |
71 | $flag = $date->is_date(); | |
72 | $flag = $date->is_short(); # i.e., has no time part | |
73 | $flag = $date->is_long(); # i.e., has time part | |
74 | $flag = $date->is_valid(); | |
75 | ||
76 | $date = Date::Calc->new([TYPE]); | |
77 | $date = Date::Calc->new([TYPE,]YEAR,MONTH,DAY[,HRS,MIN,SEC]); | |
78 | $date = Date::Calc->new($arrayref); | |
79 | $newdate = $somedate->new([TYPE]); | |
80 | $newdate = $somedate->new([TYPE,]YEAR,MONTH,DAY[,HRS,MIN,SEC]); | |
81 | $newdate = $somedate->new($arrayref); | |
82 | ||
83 | $datecopy = $date->clone(); | |
84 | $targetdate->copy($sourcedate); | |
85 | $targetdate->copy($arrayref); | |
86 | $targetdate->copy(@list); | |
87 | ||
88 | ($year,$month,$day) = $date->date([TYPE]); | |
89 | ($year,$month,$day) = $date->date([TYPE,]YEAR,MONTH,DAY[,HRS,MIN,SEC]); | |
90 | ($year,$month,$day) = $date->date($arrayref); | |
91 | ([$hrs,$min,$sec]) = $date->time([TYPE]); | |
92 | ($hrs,$min,$sec) = $date->time([TYPE,]HRS,MIN,SEC); | |
93 | ([$hrs,$min,$sec]) = $date->time($arrayref); | |
94 | ||
95 | ($year,$month,$day,$hrs,$min,$sec) = | |
96 | $date->datetime([TYPE]); | |
97 | ($year,$month,$day,$hrs,$min,$sec) = | |
98 | $date->datetime([TYPE,]YEAR,MONTH,DAY[,HRS,MIN,SEC]); | |
99 | ||
100 | $date = Date::Calc->today([FLAG]); | |
101 | $date = Date::Calc->now([FLAG]); # shorthand for --+ | |
102 | $date = Date::Calc->today_and_now([FLAG]); # <-----+ | |
103 | $date = Date::Calc->gmtime([time]); # UTC/GMT | |
104 | $date = Date::Calc->localtime([time]); # local time | |
105 | $delta = Date::Calc->tzoffset([time]); | |
106 | $date = Date::Calc->time2date([time]); # UTC/GMT | |
107 | ||
108 | $date->today([FLAG]); # updates the date part only | |
109 | $date->now([FLAG]); # updates the time part only | |
110 | $date->today_and_now([FLAG]); # updates both date and time | |
111 | $date->gmtime([time]); # updates both date and time (UTC/GMT) | |
112 | $date->localtime([time]); # updates both date and time (local time) | |
113 | $delta->tzoffset([time]); # updates both date and time | |
114 | $date->time2date([time]); # updates both date and time (UTC/GMT) | |
115 | ||
116 | $time = Date::Calc->mktime(); # same as "$time = CORE::time();" | |
117 | $time = Date::Calc->date2time(); # same as "$time = CORE::time();" | |
118 | ||
119 | $time = $date->mktime(); # converts into Unix time (local time) | |
120 | $time = $date->date2time(); # converts into Unix time (UTC/GMT) | |
121 | ||
122 | $year = $date->year([YEAR]); | |
123 | $month = $date->month([MONTH]); | |
124 | $day = $date->day([DAY]); | |
125 | $hours = $date->hours([HRS]); | |
126 | $minutes = $date->minutes([MIN]); | |
127 | $seconds = $date->seconds([SEC]); | |
128 | ||
129 | $number = $date->number([NUMBER|CODEREF]); | |
130 | $string = $date->string([NUMBER|CODEREF][,LANGUAGE]); | |
131 | ||
132 | $delta->normalize(); # renormalizes a delta vector | |
133 | ||
134 | =head2 Overloaded Operators | |
135 | ||
136 | ##################################################### | |
137 | # Scalar operands are always converted into a delta # | |
138 | # vector with that many days, i.e., [1,0,0,SCALAR] # | |
139 | ##################################################### | |
140 | ||
141 | =head2 Comparison Operators: | |
142 | ||
143 | if ($date1 < $date2) { # compares date part only | |
144 | if ($date1 <= $date2) { # compares date part only | |
145 | if ($date1 > $date2) { # compares date part only | |
146 | if ($date1 >= $date2) { # compares date part only | |
147 | if ($date1 == $date2) { # compares date part only | |
148 | if ($date1 != $date2) { # compares date part only | |
149 | ||
150 | $comp = $date1 <=> $date2; # compares date part only | |
151 | ||
152 | if ($date1 lt $date2) { # compares both date and time | |
153 | if ($date1 le $date2) { # compares both date and time | |
154 | if ($date1 gt $date2) { # compares both date and time | |
155 | if ($date1 ge $date2) { # compares both date and time | |
156 | if ($date1 eq $date2) { # compares both date and time | |
157 | if ($date1 ne $date2) { # compares both date and time | |
158 | ||
159 | $comp = $date1 cmp $date2; # compares both date and time | |
160 | ||
161 | Note that you can of course also compare two deltas, | |
162 | but not a date and a delta! | |
163 | ||
164 | ################################################## | |
165 | # Default TYPE for array refs in comparisons is: # | |
166 | # Same as other operand # | |
167 | ################################################## | |
168 | ||
169 | if ([2000,4,1] == $date) { | |
170 | if ($today > [2000,4,1]) { | |
171 | ||
172 | if ($now ge [2000,3,26,2,0,0]) { | |
173 | ||
174 | if ($delta == [18,0,0]) { | |
175 | if ($delta == -1) { | |
176 | ||
177 | =head2 Plus: | |
178 | ||
179 | $date2 = $date1 + $delta; | |
180 | $date2 = $delta + $date1; | |
181 | $date += $delta; | |
182 | $this = $date++; | |
183 | $next = ++$date; | |
184 | ||
185 | $delta3 = $delta1 + $delta2; | |
186 | $delta1 += $delta2; | |
187 | $delta += $date; # beware of implicit type change! | |
188 | $delta++; | |
189 | ++$delta; | |
190 | ||
191 | ##################################################### | |
192 | # Default TYPE for array refs in '+' operations is: # | |
193 | # Opposite of other operand # | |
194 | ##################################################### | |
195 | ||
196 | $date2 = [2000,3,26] + $delta; | |
197 | $date2 = $date1 + [+1,0,0]; | |
198 | $date2 = [0,0,-1] + $date1; | |
199 | $date2 = $date1 + 1; | |
200 | $date += [0,0,+1]; | |
201 | $date += 2; | |
202 | ||
203 | $delta3 = [1,+1,0,-1] + $delta2; | |
204 | $delta3 = $delta1 + [1,0,0,+1]; | |
205 | $delta3 = $delta1 + 1; | |
206 | $delta += [1,0,+1,0]; | |
207 | $delta += [2000,3,26]; # beware of implicit type change! | |
208 | $delta += 7; | |
209 | ||
210 | =head2 Unary Minus: | |
211 | ||
212 | $delta2 = -$delta1; | |
213 | ||
214 | =head2 Minus: | |
215 | ||
216 | $delta = $date2 - $date1; | |
217 | $date2 = $date1 - $delta; | |
218 | $date -= $delta; | |
219 | $date2 -= $date1; # beware of implicit type change! | |
220 | $this = $date--; | |
221 | $prev = --$date; | |
222 | ||
223 | $delta3 = $delta2 - $delta1; | |
224 | $delta2 -= $delta1; | |
225 | $delta--; | |
226 | --$delta; | |
227 | ||
228 | ##################################################### | |
229 | # Default TYPE for array refs in '-' operations is: # | |
230 | # Always a date # | |
231 | ##################################################### | |
232 | ||
233 | $delta = $today - [2000,3,26]; | |
234 | $delta = [2000,4,1] - $date; | |
235 | $date2 = [2000,3,26] - $delta; | |
236 | $date2 = $date1 - [1,0,0,+7]; | |
237 | $date2 = $date1 - 7; | |
238 | $date -= [1,0,0,+1]; # better add [0,0,-1] instead! | |
239 | $date2 -= [2000,3,26]; # beware of implicit type change! | |
240 | $date2 -= 1; | |
241 | ||
242 | $delta3 = [1,0,+1,0] - $delta1; | |
243 | $delta3 = $delta2 - [1,0,0,-1]; | |
244 | $delta -= [1,0,0,+1]; | |
245 | $delta -= 7; | |
246 | ||
247 | =head2 Miscellaneous Operators: | |
248 | ||
249 | $string = "$date"; | |
250 | $string = "$delta"; | |
251 | ||
252 | print "$date\n"; | |
253 | print "$delta\n"; | |
254 | ||
255 | if ($date) { # date is valid | |
256 | if ($delta) { # delta is valid | |
257 | ||
258 | $days = abs($date); | |
259 | $diff = abs($delta); # can be negative! | |
260 | ||
261 | $diff = abs(abs($delta)); # always positive | |
262 | ||
263 | =head1 DESCRIPTION | |
264 | ||
265 | =over 2 | |
266 | ||
267 | =item * | |
268 | ||
269 | FLAG | |
270 | ||
271 | "FLAG" is either 0 (for "false") or 1 (for "true"). | |
272 | ||
273 | In the case of "C<accurate_mode()>", this switches "accurate mode" | |
274 | on and off (see further below for an explanation of what that is). | |
275 | ||
276 | In the case of "C<today()>", "C<now()>" and "C<today_and_now()>", | |
277 | a "true" value indicates "GMT" (Greenwich Mean Time), as opposed | |
278 | to local time, which is the default. | |
279 | ||
280 | =item * | |
281 | ||
282 | NUMBER | |
283 | ||
284 | "NUMBER" is a number between 0 and 2 (for "number_format()" and "number()") | |
285 | or between 0 and 3 (for "delta_format()", "date_format()" and "string()"), | |
286 | indicating which of the three/four predefined formats, respectively, | |
287 | should be used for converting a date into numeric representation | |
288 | (needed for comparing dates, for instance) or string representation. | |
289 | ||
290 | Format #0 is the default at startup and the simplest of all (and | |
291 | should be fastest to calculate, too). | |
292 | ||
293 | The string representation of dates in format #0 also has the advantage of | |
294 | being sortable in chronological order (and of complying with S<ISO 8601>). | |
295 | ||
296 | (The numeric formats are (trivially) always sortable in chronological | |
297 | order of course.) | |
298 | ||
299 | The other formats are increasingly more sophisticated (in terms of | |
300 | esthetics and computation time) with increasing number: | |
301 | ||
302 | Delta number formats (short): | |
303 | ||
304 | 0 13603 | |
305 | 1 13603 | |
306 | 2 13603 | |
307 | ||
308 | Delta string formats (short): | |
309 | ||
310 | 0 '+0+0+13603' | |
311 | 1 '+0 +0 +13603' | |
312 | 2 '+0Y +0M +13603D' | |
313 | 3 '+0 Y +0 M +13603 D' | |
314 | ||
315 | Date number formats (short): | |
316 | ||
317 | 0 20010401 | |
318 | 1 730576 | |
319 | 2 730576 | |
320 | ||
321 | Date string formats (short): | |
322 | ||
323 | 0 '20010401' | |
324 | 1 '01-Apr-2001' | |
325 | 2 'Sun 1-Apr-2001' | |
326 | 3 'Sunday, April 1st 2001' | |
327 | ||
328 | Delta number formats (long): | |
329 | ||
330 | 0 13603.012959 | |
331 | 1 13603.012959 | |
332 | 2 13603.0624884259 | |
333 | ||
334 | Delta string formats (long): | |
335 | ||
336 | 0 '+0+0+13603+1+29+59' | |
337 | 1 '+0 +0 +13603 +1 +29 +59' | |
338 | 2 '+0Y +0M +13603D +1h +29m +59s' | |
339 | 3 '+0 Y +0 M +13603 D +1 h +29 m +59 s' | |
340 | ||
341 | Date number formats (long): | |
342 | ||
343 | 0 20010401.082959 | |
344 | 1 730576.082959 | |
345 | 2 730576.354155093 | |
346 | ||
347 | Date string formats (long): | |
348 | ||
349 | 0 '20010401082959' | |
350 | 1 '01-Apr-2001 08:29:59' | |
351 | 2 'Sun 1-Apr-2001 08:29:59' | |
352 | 3 'Sunday, April 1st 2001 08:29:59' | |
353 | ||
354 | If a number outside of the permitted range is specified, or if the value | |
355 | is not a code reference (see also the next section below for more details), | |
356 | the default format #0 is used instead. | |
357 | ||
358 | =item * | |
359 | ||
360 | CODEREF | |
361 | ||
362 | "CODEREF" is the reference of a subroutine which can be passed to the | |
363 | methods "number_format()", "delta_format()" and "date_format()" in order | |
364 | to install a callback function which will be called subsequently whenever | |
365 | a date (or delta) object needs to be (implicitly) converted into a number | |
366 | or string. | |
367 | ||
368 | This happens for instance when you compare two date objects, or when you | |
369 | put a date object reference in a string between double quotes. | |
370 | ||
371 | Such a "CODEREF" can also be passed to the methods "number()" and | |
372 | "string()" for explicitly converting a date object as desired. | |
373 | ||
374 | =item * | |
375 | ||
376 | LANGUAGE | |
377 | ||
378 | "LANGUAGE" is either a number in the range C<[1..Languages()]>, | |
379 | or one of the strings "C<Language_to_Text(1..Languages())>" | |
380 | (see also L<Date::Calc(3)>). | |
381 | ||
382 | =item * | |
383 | ||
384 | TYPE | |
385 | ||
386 | "TYPE" is 0 for a regular date and 1 for a delta vector (a list of | |
387 | year, month, day and optionally hours, minutes and seconds offsets). | |
388 | ||
389 | =item * | |
390 | ||
391 | Storage | |
392 | ||
393 | "Date::Calc" objects are implemented as two nested arrays. | |
394 | ||
395 | The "blessed" array (whose reference is the object reference | |
396 | you receive when calling the "new()" method) contains an | |
397 | anonymous array at position zero and the object's data in | |
398 | its remaining fields. | |
399 | ||
400 | The embedded anonymous array is used for storing the object's | |
401 | attributes (flags). | |
402 | ||
403 | Dates and delta vectors always comprise either 3 or 6 data values: | |
404 | Year, month, day plus (optionally) hours, minutes and seconds. | |
405 | ||
406 | These values are stored in the "blessed" array at positions 1..3 | |
407 | or 1..6, respectively. | |
408 | ||
409 | An object without the time values is therefore called "short", | |
410 | and an object having time values is called "long" throughout | |
411 | this manual. | |
412 | ||
413 | Hint: Whenever possible, if you do not need the time values, omit | |
414 | them, i.e., always use the "short" form of the object if possible, | |
415 | this will speed up calculations a little (the short form uses | |
416 | different (faster) functions for all calculations internally). | |
417 | ||
418 | The embedded anonymous array contains various flags: | |
419 | ||
420 | At position zero, it contains the "TYPE" indicator which determines | |
421 | whether the object is a date or a delta vector. | |
422 | ||
423 | At position 1, the object stores the "NUMBER" of one of the delta | |
424 | vector formats, or the reference of a callback function which converts | |
425 | the contents of the object into string representation if it's a delta | |
426 | vector, or "undef" if the global settings apply. | |
427 | ||
428 | At position 2, the object stores the "NUMBER" of one of the date formats, | |
429 | or the reference of a callback function which converts the contents of | |
430 | the object into string representation if it's a date, or "undef" if the | |
431 | global settings apply. | |
432 | ||
433 | At position 3, the object stores the "LANGUAGE" to be used for all | |
434 | conversions into strings (where applicable), or "undef" if the global | |
435 | language setting applies. | |
436 | ||
437 | Note that your callback functions (see the section "Callback Functions" | |
438 | further below for more details) do not need to pay attention to the | |
439 | value at position 3, the language (of the "Date::Calc" module) | |
440 | will automatically be set to this value whenever the callback | |
441 | functions are called, and automatically reset to its former value | |
442 | after the callback. | |
443 | ||
444 | So if your callback functions use the "*_to_Text*" functions from | |
445 | the "Date::Calc" module, they will automatically use the correct | |
446 | language. | |
447 | ||
448 | Be reminded though that you should B<NEVER> access the object's | |
449 | internal data directly, i.e., through their positional numbers, | |
450 | but B<ALWAYS> through their respective accessor methods, e.g.: | |
451 | ||
452 | year() | |
453 | month() | |
454 | day() | |
455 | hours() | |
456 | minutes() | |
457 | seconds() | |
458 | date() | |
459 | time() | |
460 | datetime() | |
461 | is_delta() | |
462 | is_date() | |
463 | is_short() | |
464 | is_long() | |
465 | delta_format() | |
466 | date_format() | |
467 | language() | |
468 | ||
469 | And although position 4 and onward in the embedded anonymous array is | |
470 | currently unused, it might not stay so in future releases of this module. | |
471 | ||
472 | Therefore, in case you need more attributes in a subclass of the | |
473 | "Date::Calc[::Object]" class, I suggest using values starting at | |
474 | positions a bit further up, e.g. 6, 8 or 10. | |
475 | ||
476 | =item * | |
477 | ||
478 | Invalid Dates | |
479 | ||
480 | Only "new()" allows to create objects containing possibly invalid | |
481 | dates (needed for reading in and evaluating user input, for example). | |
482 | ||
483 | =item * | |
484 | ||
485 | Usage | |
486 | ||
487 | The methods | |
488 | ||
489 | accurate_mode() | |
490 | number_format() | |
491 | delta_format() | |
492 | date_format() | |
493 | language() | |
494 | date() | |
495 | time() | |
496 | datetime() | |
497 | year() | |
498 | month() | |
499 | day() | |
500 | hours() | |
501 | minutes() | |
502 | seconds() | |
503 | ||
504 | are used for reading as well as for setting attributes. They simply | |
505 | return the values in question if they are called without parameters. | |
506 | ||
507 | The methods | |
508 | ||
509 | accurate_mode() | |
510 | number_format() | |
511 | delta_format() | |
512 | date_format() | |
513 | language() | |
514 | ||
515 | always return the previous value if a new value is set. This allows | |
516 | you to change these values temporarily and to restore their old value | |
517 | afterwards more easily (but you can also override the "format" and | |
518 | "language" settings directly when calling the "number()" or "string()" | |
519 | method). | |
520 | ||
521 | The methods | |
522 | ||
523 | date() | |
524 | time() | |
525 | datetime() | |
526 | year() | |
527 | month() | |
528 | day() | |
529 | hours() | |
530 | minutes() | |
531 | seconds() | |
532 | ||
533 | always return the new values when the corresponding values have | |
534 | been changed. | |
535 | ||
536 | The method "date()" NEVER returns the time values (hours, minutes, | |
537 | seconds) even if they have just been set using this method (which | |
538 | the method optionally allows). Otherwise it would be very hard to | |
539 | predict the exact number of values it returns, which might lead | |
540 | to errors (wrong number of parameters) elsewhere in your program. | |
541 | ||
542 | The method "datetime()" ALWAYS returns the time values (hours, | |
543 | minutes, seconds) even if the object in question lacks a time | |
544 | part. In that case, zeros are returned for hours, minutes and | |
545 | seconds instead (but the stored time part is left unchanged, | |
546 | whether it exists or not). | |
547 | ||
548 | If you do not provide values for hours, minutes and seconds when | |
549 | using the method "date()" to set the values for year, month and | |
550 | day, the time part will not be changed (whether it exists or not). | |
551 | ||
552 | If you do not provide values for hours, minutes and seconds when | |
553 | using the method "datetime()" to set the values for year, month | |
554 | and day, the time part will be filled with zeros (the time part | |
555 | will be created if necessary). | |
556 | ||
557 | If the object is short, i.e., if it does not have any time values, | |
558 | the method "time()" returns an empty list. | |
559 | ||
560 | If the object is short and the methods "hours()", "minutes()" or | |
561 | "seconds()" are used to set any of these time values, the object | |
562 | is automatically promoted to the "long" form, and the other two | |
563 | time values are filled with zeros. | |
564 | ||
565 | The following methods can also return "undef" under certain | |
566 | circumstances: | |
567 | ||
568 | delta_format() | |
569 | date_format() | |
570 | language() | |
571 | is_delta() | |
572 | is_date() | |
573 | is_short() | |
574 | is_long() | |
575 | is_valid() | |
576 | hours() | |
577 | minutes() | |
578 | seconds() | |
579 | number() | |
580 | string() | |
581 | ||
582 | The methods "delta_format()", "date_format()" and "language()" | |
583 | return "undef" when they are called as object methods and no | |
584 | individual override has been defined for the object in question. | |
585 | ||
586 | The "is_*()" predicate methods return "undef" if the object in | |
587 | question does not have the expected internal structure. This can | |
588 | happen for instance when you create an empty object with "new()". | |
589 | ||
590 | When called without parameters, the methods "hours()", "minutes()" | |
591 | and "seconds()" return "undef" if the object in question does not | |
592 | have a time part. | |
593 | ||
594 | The methods "number()" and "string()" return "undef" if the object | |
595 | in question is not valid (i.e., if "is_valid()" returns "undef" or | |
596 | false). | |
597 | ||
598 | And finally, the methods | |
599 | ||
600 | copy() | |
601 | today() | |
602 | now() | |
603 | today_and_now() | |
604 | gmtime() | |
605 | localtime() | |
606 | tzoffset() | |
607 | time2date() | |
608 | normalize() | |
609 | ||
610 | return the object reference of the (target) object in question | |
611 | for convenience. | |
612 | ||
613 | =item * | |
614 | ||
615 | Import/Export | |
616 | ||
617 | Note that you can import and export Unix "time" values using the | |
618 | methods "gmtime()", "localtime()", "mktime()", "date2time()" and | |
619 | "time2date()", both as local time or as UTC/GMT. | |
620 | ||
621 | =item * | |
622 | ||
623 | Accurate Mode | |
624 | ||
625 | The method "accurate_mode()" controls the internal flag which | |
626 | determines which of two modes of operation is used. | |
627 | ||
628 | When set to true (the default at startup), delta vectors are | |
629 | calculated to give the exact difference in days between two | |
630 | dates. The "year" and "month" entries in the resulting delta | |
631 | vector are always zero in that case. | |
632 | ||
633 | If "accurate mode" is switched off (when the corresponding | |
634 | flag is set to false), delta vectors are calculated with | |
635 | year and month differences. | |
636 | ||
637 | E.g., the difference between C<[1999,12,6]> and C<[2000,6,24]> | |
638 | is C<[+0 +0 +201]> (plus 201 days) in accurate mode and | |
639 | C<[+1 -6 +18]> (plus one year, minus 6 months, plus 18 days) | |
640 | when accurate mode is switched off. | |
641 | ||
642 | (The delta vector is calculated by simply taking the difference | |
643 | in years, the difference in months and the difference in days.) | |
644 | ||
645 | Because years and months have varying lengths in terms of days, | |
646 | the latter is less accurate than the former because it depends | |
647 | on the context of the two dates of which it represents the | |
648 | difference. Added to a different date, the latter delta vector | |
649 | may yield a different offset in terms of days. | |
650 | ||
651 | Beware also that - for the same reason - the absolute value | |
652 | ("C<abs()>") of a delta vector returns a fictitious number | |
653 | of days if the delta vector contains non-zero values for | |
654 | "year" and/or "month" (see also next section below for | |
655 | more details). | |
656 | ||
657 | Example: | |
658 | ||
659 | The difference between C<[2000,1,1]> and C<[2000,3,1]> is | |
660 | C<[+0 +0 +60]> in accurate mode and C<[+0 +2 +0]> else (one | |
661 | could also call this "year-month-day mode" or "YMD mode" for | |
662 | short). | |
663 | ||
664 | When added to the date C<[2000,4,1]>, the "accurate" delta | |
665 | vector yields the date C<[2000,5,31]>, whereas the other delta | |
666 | vector yields the date C<[2000,6,1]>. | |
667 | ||
668 | Moreover, when added to the date C<[1999,1,1]>, the "accurate" | |
669 | delta vector yields the date C<[1999,3,2]>, whereas the "inaccurate" | |
670 | delta vector yields the date C<[1999,3,1]>. | |
671 | ||
672 | Depending on what you want, the one or the other mode may suit | |
673 | you better. | |
674 | ||
675 | =item * | |
676 | ||
677 | Absolute Value | |
678 | ||
679 | Note that "C<abs($date)>" and "C<abs($delta)>" are just shorthands | |
680 | for "C<$date-E<gt>number()>" and "C<$delta-E<gt>number()>". | |
681 | ||
682 | The operator "C<abs()>", when applied to a date or delta vector, | |
683 | returns the corresponding number of days (see below for an exception | |
684 | to this), with the time part (if available) represented by a fraction | |
685 | after the decimal point. | |
686 | ||
687 | In the case of dates, the absolute value (to the left of the | |
688 | decimal point) is the number of days since the 1st of January | |
689 | S<1 A.D.> (by extrapolating the Gregorian calendar back beyond | |
690 | its "natural" limit of 1582 A.D.) B<PLUS ONE>. | |
691 | ||
692 | (I.e., the absolute value of the 1st of January 1 A.D. is 1.) | |
693 | ||
694 | Exception: | |
695 | ||
696 | If the "NUMBER" or "number_format()" is set to 0 (the default | |
697 | setting), the absolute value of a date to the left of the decimal | |
698 | point is "yyyymmdd", i.e., the number in which the uppermost four | |
699 | digits correspond to the year, the next lower two digits to the | |
700 | month and the lowermost two digits to the day. | |
701 | ||
702 | In the case of delta vectors, the absolute value (to the left | |
703 | of the decimal point) is simply the difference in days (but | |
704 | see also below). | |
705 | ||
706 | Note that the absolute value of a delta vector can be negative! | |
707 | ||
708 | If you want a positive value in all cases, apply the "C<abs()>" | |
709 | operator again, i.e., "C<$posdiff = abs(abs($delta));>". | |
710 | ||
711 | If the delta vector contains non-zero values for "year" and/or | |
712 | "month" (see also the discussion of "Accurate Mode" in the section | |
713 | above), an exact representation in days cannot be calculated, | |
714 | because years and months do not have fixed equivalents in days. | |
715 | ||
716 | If nevertheless you attempt to calculate the absolute value of | |
717 | such a delta vector, a fictitious value is returned, which is | |
718 | calculated by simply multiplying the year difference with 12, | |
719 | adding the month difference, multiplying this sum with 31 and | |
720 | finally adding the day difference. | |
721 | ||
722 | Beware that because of this, the absolute values of delta | |
723 | vectors are not necessarily contiguous. | |
724 | ||
725 | Moreover, since there is more than one way to express the | |
726 | difference between two dates, comparisons of delta vectors | |
727 | may not always yield the expected result. | |
728 | ||
729 | Example: | |
730 | ||
731 | The difference between the two dates C<[2000,4,30]> and | |
732 | C<[2001,5,1]> can be expressed as C<[+1 +1 -29]>, or as | |
733 | C<[+1 +0 +1]>. | |
734 | ||
735 | The first delta vector has an absolute value of 374, | |
736 | whereas the latter delta vector has an absolute value | |
737 | of only 373 (while the true difference in days between | |
738 | the two dates is 366). | |
739 | ||
740 | If the date or delta vector has a time part, the time is returned | |
741 | as a fraction of a full day after the decimal point as follows: | |
742 | ||
743 | If the "NUMBER" or "number_format()" is set to 0 (the default | |
744 | setting) or 1, this fraction is simply ".hhmmss", i.e., the | |
745 | two digits after the decimal point represent the hours, the | |
746 | next two digits the minutes and the last two digits the seconds. | |
747 | ||
748 | Note that you cannot simply add and subtract these values to | |
749 | yield meaningful dates or deltas again, you can only use them | |
750 | for comparisons (equal, not equal, less than, greater than, | |
751 | etc.). If you want to add/subtract, read on: | |
752 | ||
753 | Only when the "NUMBER" or "number_format()" is set to 2, this | |
754 | fraction will be the equivalent number of seconds (i.e., | |
755 | C<(((hours * 60) + minutes) * 60) + seconds>) divided by the | |
756 | number of seconds in a full day (i.e., C<24*60*60 = 86400>), | |
757 | or C<0/86400>, C<1/86400>, ... , C<86399/86400>. | |
758 | ||
759 | In other words, the (mathematically correct) fraction of a day. | |
760 | ||
761 | You can safely perform arithmetics with these values as far | |
762 | as the internal precision of your vendor's implementation | |
763 | of the C run-time library (on which Perl depends) will permit. | |
764 | ||
765 | =item * | |
766 | ||
767 | Renormalizing Delta Vectors | |
768 | ||
769 | When adding or subtracting delta vectors to/from one another, | |
770 | the addition or subtraction takes place component by component. | |
771 | ||
772 | Example: | |
773 | ||
774 | [+0 +0 +0 +3 +29 +50] + [+0 +0 +0 +0 +55 +5] = [+0 +0 +0 +3 +84 +55] | |
775 | [+0 +0 +0 +3 +29 +50] - [+0 +0 +0 +0 +55 +5] = [+0 +0 +0 +3 -26 +45] | |
776 | ||
777 | This may result in time values outside the usual ranges (C<[-23..+23]> | |
778 | for hours and C<[-59..+59]> for minutes and seconds). | |
779 | ||
780 | Note that even though the delta value for days will often become quite large, | |
781 | it is impossible to renormalize this value because there is no constant | |
782 | conversion factor from days to months (should it be 28, 29, 30 or 31?). | |
783 | ||
784 | If accurate mode (see further above for what that is) is switched off, | |
785 | delta vectors can also contain non-zero values for years and months. If | |
786 | you add or subtract these, the value for months can lie outside the | |
787 | range C<[-11..11]>, which isn't wrong, but may seem funny. | |
788 | ||
789 | Therefore, the "normalize()" method will also renormalize the "months" | |
790 | value, if and only if accurate mode has been switched off. (!) | |
791 | ||
792 | (Hence, switch accurate mode B<ON> temporarily if you B<DON'T> want | |
793 | the renormalization of the "months" value to happen.) | |
794 | ||
795 | If you want to force the time values from the example above back into | |
796 | their proper ranges, use the "normalize()" method as follows: | |
797 | ||
798 | print "[$delta]\n"; | |
799 | $delta->normalize(); | |
800 | print "[$delta]\n"; | |
801 | ||
802 | This will print | |
803 | ||
804 | [+0 +0 +0 +3 +84 +55] | |
805 | [+0 +0 +0 +4 +24 +55] | |
806 | ||
807 | for the first and | |
808 | ||
809 | [+0 +0 +0 +3 -26 +45] | |
810 | [+0 +0 +0 +2 +34 +45] | |
811 | ||
812 | for the second delta vector from the example further above. | |
813 | ||
814 | Note that the values for days, hours, minutes and seconds are | |
815 | guaranteed to have the same sign after the renormalization. | |
816 | ||
817 | Under "normal" circumstances, i.e., when accurate mode is on (the | |
818 | default), this method only has an effect on the time part of the | |
819 | delta vector. | |
820 | ||
821 | If the delta vector in question does not have a time part, nothing | |
822 | is done. | |
823 | ||
824 | If accurate mode is off, the "months" value is also normalized, | |
825 | i.e., if it lies outside of the range C<[-11..11]>, integer | |
826 | multiples of 12 are added to the "years" value and subtracted | |
827 | from the "months" value. Moreover, the "months" value is | |
828 | guaranteed to have the same sign as the values for days, | |
829 | hours, minutes and seconds, unless the "months" value is zero | |
830 | or the values for days, hours, minutes and seconds are all zero. | |
831 | ||
832 | If the object in question is a date and if warnings are enabled, | |
833 | the message "normalizing a date is a no-op" will be printed to | |
834 | STDERR. | |
835 | ||
836 | If the object in question is not a valid "Date::Calc" object, | |
837 | nothing is done. | |
838 | ||
839 | The method returns its object's reference, which allows chaining | |
840 | of method calls, as in the following example: | |
841 | ||
842 | @time = $delta->normalize()->time(); | |
843 | ||
844 | =item * | |
845 | ||
846 | Callback Functions | |
847 | ||
848 | Note that you are not restricted to the built-in formats | |
849 | (numbered from 0 to 2 for "number_format()" and "number()" | |
850 | and from 0 to 3 for "delta_format()", "date_format()" and | |
851 | "string()") for converting a date or delta object into a | |
852 | number or string. | |
853 | ||
854 | You can also provide your own function(s) for doing so, in | |
855 | order to suit your own taste or needs, by passing a subroutine | |
856 | reference to the appropriate method, i.e., "number_format()", | |
857 | "number()", "delta_format()", "date_format()" and "string()". | |
858 | ||
859 | You can pass a handler to only one or more of these methods, | |
860 | or to all of them, as you like. You can use different callback | |
861 | functions, or the same for all. | |
862 | ||
863 | In order to facilitate the latter, and in order to make the | |
864 | decoding of the various cases easier for you, the callback | |
865 | function receives a uniquely identifying function code as | |
866 | its second parameter: | |
867 | ||
868 | 0 = TO_NUMBER | IS_DATE | IS_SHORT (number[_format]) | |
869 | 1 = TO_NUMBER | IS_DATE | IS_LONG (number[_format]) | |
870 | 2 = TO_NUMBER | IS_DELTA | IS_SHORT (number[_format]) | |
871 | 3 = TO_NUMBER | IS_DELTA | IS_LONG (number[_format]) | |
872 | 4 = TO_STRING | IS_DATE | IS_SHORT (string|date_format) | |
873 | 5 = TO_STRING | IS_DATE | IS_LONG (string|date_format) | |
874 | 6 = TO_STRING | IS_DELTA | IS_SHORT (string|delta_format) | |
875 | 7 = TO_STRING | IS_DELTA | IS_LONG (string|delta_format) | |
876 | ||
877 | The first parameter of the callback function is of course the | |
878 | handle of the object in question itself (therefore, the callback | |
879 | function can actually be an object method - but not a class method, | |
880 | for obvious reasons). | |
881 | ||
882 | The handler should return the resulting number or string, as | |
883 | requested. | |
884 | ||
885 | BEWARE that you should NEVER rely upon any knowledge of the | |
886 | object's internal structure, as this may be subject to change! | |
887 | ||
888 | ALWAYS use the test and access methods provided by this module! | |
889 | ||
890 | Example: | |
891 | ||
892 | sub handler | |
893 | { | |
894 | my($self,$code) = @_; | |
895 | ||
896 | if ($code == 0) # TO_NUMBER | IS_DATE | IS_SHORT | |
897 | { | |
898 | return Date_to_Days( $self->date() ); | |
899 | } | |
900 | elsif ($code == 1) # TO_NUMBER | IS_DATE | IS_LONG | |
901 | { | |
902 | return Date_to_Days( $self->date() ) + | |
903 | ( ( $self->hours() * 60 + | |
904 | $self->minutes() ) * 60 + | |
905 | $self->seconds() ) / 86400; | |
906 | } | |
907 | elsif ($code == 2) # TO_NUMBER | IS_DELTA | IS_SHORT | |
908 | { | |
909 | return ( $self->year() * 12 + | |
910 | $self->month() ) * 31 + | |
911 | $self->day(); | |
912 | } | |
913 | elsif ($code == 3) # TO_NUMBER | IS_DELTA | IS_LONG | |
914 | { | |
915 | return ( $self->year() * 12 + | |
916 | $self->month() ) * 31 + | |
917 | $self->day() + | |
918 | ( ( $self->hours() * 60 + | |
919 | $self->minutes() ) * 60 + | |
920 | $self->seconds() ) / 86400; | |
921 | } | |
922 | elsif ($code == 4) # TO_STRING | IS_DATE | IS_SHORT | |
923 | { | |
924 | return join( "/", $self->date() ); | |
925 | } | |
926 | elsif ($code == 5) # TO_STRING | IS_DATE | IS_LONG | |
927 | { | |
928 | return join( "/", $self->date() ) . " " . | |
929 | join( ":", $self->time() ); | |
930 | } | |
931 | elsif ($code == 6) # TO_STRING | IS_DELTA | IS_SHORT | |
932 | { | |
933 | return join( "|", $self->date() ); | |
934 | } | |
935 | elsif ($code == 7) # TO_STRING | IS_DELTA | IS_LONG | |
936 | { | |
937 | return join( "|", $self->datetime() ); | |
938 | } | |
939 | else | |
940 | { | |
941 | die "internal error"; | |
942 | } | |
943 | } | |
944 | ||
945 | Date::Calc->number_format(\&handler); | |
946 | Date::Calc->delta_format(\&handler); | |
947 | Date::Calc->date_format(\&handler); | |
948 | ||
949 | This sets our handler to take care of all automatic conversions, | |
950 | such as needed when comparing dates or when interpolating a string | |
951 | in double quotes which contains a date object. | |
952 | ||
953 | To deactivate a handler, simply pass a valid format number to the | |
954 | method in question, e.g.: | |
955 | ||
956 | Date::Calc->number_format(0); | |
957 | Date::Calc->delta_format(2); | |
958 | Date::Calc->date_format(3); | |
959 | ||
960 | When calling the "number()" or "string()" method explicitly, you can | |
961 | pass a different format number (than the global setting), like this: | |
962 | ||
963 | $number = $date->number(2); | |
964 | $string = $date->string(1); | |
965 | ||
966 | You can also pass a handler's reference, like so: | |
967 | ||
968 | $number = $date->number(\&handler); | |
969 | $string = $date->string(\&handler); | |
970 | ||
971 | This overrides the global setting for the duration of the call of | |
972 | "number()" or "string()" (but doesn't change the global setting | |
973 | itself). | |
974 | ||
975 | Moreover, you can also define individual overrides for the date and | |
976 | the delta vector formats (but not the number format) for individual | |
977 | objects, e.g.: | |
978 | ||
979 | $date->delta_format(1); | |
980 | $date->date_format(2); | |
981 | ||
982 | $date->delta_format(\&handler); | |
983 | $date->date_format(\&handler); | |
984 | ||
985 | In order to deactivate an individual handler for an object, and/or | |
986 | in order to deactivate any override altogether (so that the global | |
987 | settings apply again), you have to pass "undef" explicitly to the | |
988 | method in question: | |
989 | ||
990 | $date->delta_format(undef); | |
991 | $date->date_format(undef); | |
992 | ||
993 | You can also define a language for individual objects (see the | |
994 | next section immediately below for more details). | |
995 | ||
996 | If such an individual language override has been set, and if your | |
997 | callback handlers only use the "*_to_Text*" functions from the | |
998 | "Date::Calc" module to produce any text, the text produced will | |
999 | automatically be in the desired language. | |
1000 | ||
1001 | This is because the language is set to the value determined by | |
1002 | the individual override before the callback handler is executed, | |
1003 | and reset to its previous value afterwards. | |
1004 | ||
1005 | =item * | |
1006 | ||
1007 | Languages | |
1008 | ||
1009 | Note that this module is completely transparent to the setting | |
1010 | of a language in "Date::Calc". This means that you can choose a | |
1011 | language in "Date::Calc" (with the "Language()" function) and all | |
1012 | dates subsequently printed by this module will automatically be | |
1013 | in that language - provided that you use the built-in formats of | |
1014 | this module, or that you use the "*to_Text*" functions from the | |
1015 | "Date::Calc" module in your formatting handler (callback function). | |
1016 | ||
1017 | However, this global language setting can be overridden for | |
1018 | individual date (or delta) objects by using the B<OBJECT> method | |
1019 | ||
1020 | $oldlang = $date->language($newlang); | |
1021 | ||
1022 | (The global setting is not altered by this in any way.) | |
1023 | ||
1024 | In order to deactivate such an individual language setting | |
1025 | (so that the global setting applies again), simply pass the | |
1026 | value "undef" explicitly to the "language()" object method: | |
1027 | ||
1028 | $date->language(undef); | |
1029 | ||
1030 | The B<CLASS> method | |
1031 | ||
1032 | $oldlang = Date::Calc->language($newlang); | |
1033 | ||
1034 | is just a convenient wrapper around the "Language()" function, | |
1035 | which allows you to enter language numbers (as returned by the | |
1036 | "Decode_Language()" function) or strings (as returned by the | |
1037 | "Language_to_Text()" function), at your option. | |
1038 | ||
1039 | The "language()" method (both class and object) always returns | |
1040 | the B<NAME> (one of "C<Language_to_Text(1..Languages())>") of | |
1041 | the current setting (and never its number). | |
1042 | ||
1043 | =item * | |
1044 | ||
1045 | Exported Functions | |
1046 | ||
1047 | The "Date::Calc::Object" package imports ":all" functions exported | |
1048 | by the "Date::Calc" module and re-exports them, for conveniency. | |
1049 | ||
1050 | This allows you to write | |
1051 | ||
1052 | use Date::Calc::Object qw(...); | |
1053 | ||
1054 | instead of | |
1055 | ||
1056 | use Date::Calc qw(...); | |
1057 | ||
1058 | but with exactly the same semantics. The difference is that | |
1059 | the object-oriented frontend is loaded additionally in the | |
1060 | first case. | |
1061 | ||
1062 | As with "Date::Calc" you can use the ":all" tag to import all | |
1063 | of "Date::Calc"'s functions: | |
1064 | ||
1065 | use Date::Calc::Object qw(:all); | |
1066 | ||
1067 | In addition to the functions exported by "Date::Calc", the | |
1068 | "Date::Calc::Object" package offers some utility functions | |
1069 | of its own for export: | |
1070 | ||
1071 | $year = shift_year(\@_); | |
1072 | ($year,$mm,$dd) = shift_date(\@_); | |
1073 | ($hrs,$min,$sec) = shift_time(\@_); | |
1074 | ($year,$mm,$dd,$hrs,$min,$sec) = shift_datetime(\@_); | |
1075 | ||
1076 | These functions enable your subroutines or methods to accept | |
1077 | a "Date::Calc" (or subclass) date object, an (anonymous) array | |
1078 | or a list (containing the necessary values) as parameters | |
1079 | B<INTERCHANGEABLY>. | |
1080 | ||
1081 | You can import all of these auxiliary functions by using an | |
1082 | ":aux" tag: | |
1083 | ||
1084 | use Date::Calc::Object qw(:aux); | |
1085 | ||
1086 | If you want to import both all of the "Date::Calc" functions | |
1087 | as well as all these auxiliary functions, use the ":ALL" tag: | |
1088 | ||
1089 | use Date::Calc::Object qw(:ALL); | |
1090 | ||
1091 | =item * | |
1092 | ||
1093 | Subclassing | |
1094 | ||
1095 | In case you want to subclass "Date::Calc" objects and to add | |
1096 | new attributes of your own, it is recommended that you proceed | |
1097 | as follows (the following will be considered as a part of the | |
1098 | module's "contract of use" - which might be subject to change | |
1099 | in the future, however): | |
1100 | ||
1101 | Define a constant for the index of each attribute you want to | |
1102 | add, currently starting no lower than "4", at the top of your | |
1103 | subclass: | |
1104 | ||
1105 | use constant ATTRIB1 => 4; | |
1106 | use constant ATTRIB2 => 5; | |
1107 | use constant ATTRIB3 => 6; | |
1108 | ... | |
1109 | ||
1110 | It is recommended that you use constants (which are easy to | |
1111 | change), because I someday might want to require the element | |
1112 | with index "4" for a new attribute of my own... C<:-)> | |
1113 | ||
1114 | Then access your attributes like so (e.g. after calling | |
1115 | "C<$self = SUPER-E<gt>new();>" in your constructor method): | |
1116 | ||
1117 | $self->[0][ATTRIB1] = 'value1'; | |
1118 | $self->[0][ATTRIB2] = 'value2'; | |
1119 | $self->[0][ATTRIB3] = 'value3'; | |
1120 | ... | |
1121 | ||
1122 | Beware that if you put anything other than numbers or strings | |
1123 | into your attributes, the methods "clone()" and "copy()" might | |
1124 | not work as expected anymore! | |
1125 | ||
1126 | Especially if your attributes contain references to other data | |
1127 | structures, only the references will be copied, but not the data | |
1128 | structures themselves. | |
1129 | ||
1130 | This may not be what you want. | |
1131 | ||
1132 | (You will have to override these two methods and write some | |
1133 | of your own if not.) | |
1134 | ||
1135 | In order for the overloaded operators and the "shift_*()" | |
1136 | auxiliary functions from the "Date::Calc::Object" package | |
1137 | to work properly (the latter of which are heavily used in | |
1138 | the "Date::Calendar[::Year]" modules, for instance), the | |
1139 | package name of your subclass (= the one your objects will | |
1140 | be blessed into) is B<REQUIRED> to contain a "::". | |
1141 | ||
1142 | Note that you should B<ONLY> subclass "Date::Calc", B<NEVER> | |
1143 | "Date::Calc::Object", since subclassing the latter is less | |
1144 | efficient (because "Date::Calc::Object" is just an empty class | |
1145 | which inherits from "Date::Calc" - subclassing "Date::Calc::Object" | |
1146 | would thus just introduce an additional name space layer to search | |
1147 | during Perl's runtime method binding process). | |
1148 | ||
1149 | If you give your subclass a package name below/inside the | |
1150 | "Date::" namespace, you will also benefit from the fact that | |
1151 | all error messages produced by the "Date::Calc[::Object]" module | |
1152 | (and also the "Date::Calendar[::Year]" modules, by the way) | |
1153 | will appear to have originated from the place outside of all | |
1154 | "C</^Date::/>" modules (including yours) where one of the "Date::" | |
1155 | modules was first called - i.e., all errors are always blamed | |
1156 | on the user, no matter how deeply nested inside the "Date::" | |
1157 | modules they occur, and do not usually refer to places inside | |
1158 | any of the "Date::" modules (this assumes that there are no | |
1159 | bugs in the "Date::" modules, and that all errors are always | |
1160 | the user's fault C<:-)>). | |
1161 | ||
1162 | Moreover, your module's own error messages will behave in the | |
1163 | same way if you "C<use Carp::Clan qw(^Date::);>" at the top of | |
1164 | your module and if you produce all error messages using "carp()" | |
1165 | and "croak()" (instead of "warn()" and "die()", respectively). | |
1166 | ||
1167 | =back | |
1168 | ||
1169 | =head1 EXAMPLES | |
1170 | ||
1171 | =over 3 | |
1172 | ||
1173 | =item 1) | |
1174 | ||
1175 | # Switch to summer time: | |
1176 | $now = Date::Calc->now(); | |
1177 | if (($now ge [2000,3,26,2,0,0]) and | |
1178 | ($now lt [2000,3,26,3,0,0])) | |
1179 | { | |
1180 | $now += [0,0,0,1,0,0]; | |
1181 | } | |
1182 | ||
1183 | =item 2) | |
1184 | ||
1185 | use Date::Calc::Object qw(:all); | |
1186 | ||
1187 | Date::Calc->date_format(3); | |
1188 | ||
1189 | $date = 0; | |
1190 | while (!$date) | |
1191 | { | |
1192 | print "Please enter the date of your birthday (day-month-year): "; | |
1193 | $date = Date::Calc->new( Decode_Date_EU( scalar(<STDIN>) ) ); | |
1194 | if ($date) | |
1195 | { | |
1196 | $resp = 0; | |
1197 | while ($resp !~ /^\s*[YyNn]/) | |
1198 | { | |
1199 | print "Your birthday is: $date\n"; | |
1200 | print "Is that correct? (yes/no) "; | |
1201 | $resp = <STDIN>; | |
1202 | } | |
1203 | $date = 0 unless ($resp =~ /^\s*[Yy]/) | |
1204 | } | |
1205 | else | |
1206 | { | |
1207 | print "Unable to parse your birthday. Please try again.\n"; | |
1208 | } | |
1209 | } | |
1210 | ||
1211 | if ($date + [18,0,0] <= [Today()]) | |
1212 | { print "Ok, you are over 18.\n"; } | |
1213 | else | |
1214 | { print "Sorry, you are under 18!\n"; } | |
1215 | ||
1216 | =back | |
1217 | ||
1218 | For more examples, see the "examples" subdirectory in this distribution, | |
1219 | and their descriptions in the file "EXAMPLES.txt". | |
1220 | ||
1221 | =head1 SEE ALSO | |
1222 | ||
1223 | Date::Calc(3), Date::Calendar(3), | |
1224 | Date::Calendar::Year(3), Date::Calendar::Profiles(3). | |
1225 | ||
1226 | =head1 VERSION | |
1227 | ||
1228 | This man page documents "Date::Calc::Object" version 5.3. | |
1229 | ||
1230 | =head1 AUTHOR | |
1231 | ||
1232 | Steffen Beyer | |
1233 | mailto:sb@engelschall.com | |
1234 | http://www.engelschall.com/u/sb/download/ | |
1235 | ||
1236 | =head1 COPYRIGHT | |
1237 | ||
1238 | Copyright (c) 2000 - 2002 by Steffen Beyer. All rights reserved. | |
1239 | ||
1240 | =head1 LICENSE | |
1241 | ||
1242 | This package is free software; you can redistribute it and/or | |
1243 | modify it under the same terms as Perl itself, i.e., under the | |
1244 | terms of the "Artistic License" or the "GNU General Public License". | |
1245 | ||
1246 | Please refer to the files "Artistic.txt" and "GNU_GPL.txt" | |
1247 | in this distribution for details! | |
1248 | ||
1249 | =head1 DISCLAIMER | |
1250 | ||
1251 | This package is distributed in the hope that it will be useful, | |
1252 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
1253 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
1254 | ||
1255 | See the "GNU General Public License" for more details. | |
1256 |