Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / perl-5.8.0 / lib / site_perl / 5.8.0 / Date / Manip.pod
CommitLineData
86530b38
AT
1# Copyright (c) 1995-2003 Sullivan Beck. All rights reserved.
2# This program is free software; you can redistribute it and/or modify it
3# under the same terms as Perl itself.
4
5=head1 NAME
6
7Date::Manip - date manipulation routines
8
9=head1 SYNOPSIS
10
11 use Date::Manip;
12
13 $date = ParseDate(\@args);
14 $date = ParseDate($string);
15 $date = ParseDate(\$string);
16
17 @date = UnixDate($date,@format);
18 $date = UnixDate($date,@format);
19
20 $delta = ParseDateDelta(\@args);
21 $delta = ParseDateDelta($string);
22 $delta = ParseDateDelta(\$string);
23
24 @str = Delta_Format($delta,$dec,@format);
25 $str = Delta_Format($delta,$dec,@format);
26
27 $recur = ParseRecur($string,$base,$date0,$date1,$flags);
28 @dates = ParseRecur($string,$base,$date0,$date1,$flags);
29
30 $flag = Date_Cmp($date1,$date2);
31
32 $d = DateCalc($d1,$d2 [,$errref] [,$del]);
33
34 $date = Date_SetTime($date,$hr,$min,$sec);
35 $date = Date_SetTime($date,$time);
36
37 $date = Date_SetDateField($date,$field,$val [,$nocheck]);
38
39 $date = Date_GetPrev($date,$dow,$today,$hr,$min,$sec);
40 $date = Date_GetPrev($date,$dow,$today,$time);
41
42 $date = Date_GetNext($date,$dow,$today,$hr,$min,$sec);
43 $date = Date_GetNext($date,$dow,$today,$time);
44
45 $version = DateManipVersion;
46
47 $flag = Date_IsWorkDay($date [,$flag]);
48
49 $date = Date_NextWorkDay($date,$off [,$time]);
50 $date = Date_PrevWorkDay($date,$off [,$time]);
51
52 $name = Date_IsHoliday($date);
53
54 $listref = Events_List($date);
55 $listref = Events_List($date0,$date1);
56
57 &Date_Init();
58 &Date_Init("VAR=VAL","VAR=VAL",...);
59 @list = Date_Init();
60 @list = Date_Init("VAR=VAL","VAR=VAL",...);
61
62The above routines all check to make sure that Date_Init is called. If it
63hasn't been, they will call it automatically. As a result, there is usually
64no need to call Date_Init explicitely unless you want to change some of the
65config variables (described below).
66
67The following routines are used by the above routines (though they can also
68be called directly). $y may be entered as either a 2 or 4 digit year (it
69will be converted to a 4 digit year based on the variable YYtoYYYY
70described below). Month and day should be numeric in all cases. Most (if
71not all) of the information below can be gotten from UnixDate which is
72really the way I intended it to be gotten, but there are reasons to use
73these (these are significantly faster).
74
75***NOTE*** Unlike the routines listed above, the following routines do NOT
76explicitely call Date_Init. You must make sure that Date_Init has been
77called, either by you explicitely, or by one of the above routines before you
78use these routines.
79
80 $day = Date_DayOfWeek($m,$d,$y);
81 $secs = Date_SecsSince1970($m,$d,$y,$h,$mn,$s);
82 $secs = Date_SecsSince1970GMT($m,$d,$y,$h,$mn,$s);
83 $days = Date_DaysSince1BC($m,$d,$y);
84 $day = Date_DayOfYear($m,$d,$y);
85 $days = Date_DaysInYear($y);
86 $wkno = Date_WeekOfYear($m,$d,$y,$first);
87 $flag = Date_LeapYear($y);
88 $day = Date_DaySuffix($d);
89 $tz = Date_TimeZone();
90 ($y,$m,$d,$h,$mn,$s) = Date_NthDayOfYear($y,$n);
91
92=head1 DESCRIPTION
93
94This is a set of routines designed to make any common date/time
95manipulation easy to do. Operations such as comparing two times,
96calculating a time a given amount of time from another, or parsing
97international times are all easily done. From the very beginning, the main
98focus of Date::Manip has been to be able to do ANY desired date/time
99operation easily, not necessarily quickly. Also, it is definitely oriented
100towards the type of operations we (as people) tend to think of rather than
101those operations used routinely by computers. There are other modules that
102can do a subset of the operations available in Date::Manip much quicker
103than those presented here, so be sure to read the section SHOULD I USE
104DATE::MANIP below before deciding which of the Date and Time modules from
105CPAN is for you.
106
107Date::Manip deals with time as it is presented the Gregorian calendar (the
108one currently in use). The Julian calendar defined leap years as every 4th
109year. The Gregorian calendar improved this by making every 100th year NOT
110a leap year, unless it was also the 400th year. The Gregorian calendar has
111been extrapolated back to the year 0000 AD and forward to the year 9999 AD.
112Note that in historical context, the Julian calendar was in use until 1582
113when the Gregorian calendar was adopted by the Catholic church. Protestant
114countries did not accept it until later; Germany and Netherlands in 1698,
115British Empire in 1752, Russia in 1918. Note that the Gregorian calendar
116is itself imperfect and at some point will need to be corrected. No attempt
117is made to correct for that, and my great great great grandchildren will be
118long dead before this even occurs, so it's not an immediate concern. Yes,
119this is the same type of attitute that caused the great Y2K problem... but
120I have an excuse: I don't know what the correction will be, so I can't
121possible implement it. Nobody doubted that the year after 1999 would be
122known as 2000 :-).
123
124Date::Manip is therefore not equipped to truly deal with historical dates,
125but should be able to perform (virtually) any operation dealing with a
126modern time and date.
127
128Date::Manip has (or will have) functionality to work with several fundamental
129types of data.
130
131=over 4
132
133=item DATE
134
135Although the word date is used extensively here, it is actually somewhat
136misleading. Date::Manip works with the full date AND time (year, month,
137day, hour, minute, second and weeks when appropriate). It doesn't work
138with fractional seconds. Timezones are also supported to some extent.
139
140NOTE: Much better support for timezones (including Daylight Savings Time)
141is planned for the future.
142
143=item DELTA
144
145This refers to a duration or elapsed time. One thing to note is that, as
146used in this module, a delta refers only to the amount of time elapsed. It
147includes no information about a starting or ending time.
148
149=item RECURRENCE
150
151A recurrence is simply a notation for defining when a recurring event
152occurs. For example, if an event occurs every other Friday or every
1534 hours, this can be defined as a recurrence. With a recurrence and a
154starting and ending date, you can get a list of dates in that period when
155a recurring event occurs.
156
157=item GRAIN
158
159The granularity of a time basically refers to how accurate you wish to
160treat a date. For example, if you want to compare two dates to see if
161they are identical at a granularity of days, then they only have to occur
162on the same day. At a granularity of an hour, they have to occur within
163an hour of each other, etc.
164
165NOTE: Support for this will be added in the future.
166
167=item HOLIDAYS and EVENTS
168
169These are basically a named time. Holidays are used in business mode
170calculations. Events allow things like calendar and scheduling
171applications to be designed much more easily.
172
173=back
174
175Among other things, Date::Manip allow you to:
176
1771. Enter a date and be able to choose any format convenient
178
1792. Compare two dates, entered in widely different formats
180 to determine which is earlier
181
1823. Extract any information you want from ANY date using a
183 format string similar to the Unix date command
184
1854. Determine the amount of time between two dates
186
1875. Add a time offset to a date to get a second date (i.e.
188 determine the date 132 days ago or 2 years and 3 months
189 after Jan 2, 1992)
190
1916. Work with dates with dates using international formats
192 (foreign month names, 12/10/95 referring to October
193 rather than December, etc.).
194
1957. To find a list of dates where a recurring event happens.
196
197Each of these tasks is trivial (one or two lines at most) with this package.
198
199=head1 EXAMPLES
200
201In the documentation below, US formats are used, but in most (if not all)
202cases, a non-English equivalent will work equally well.
203
2041. Parsing a date from any convenient format
205
206 $date = ParseDate("today");
207 $date = ParseDate("1st thursday in June 1992");
208 $date = ParseDate("05/10/93");
209 $date = ParseDate("12:30 Dec 12th 1880");
210 $date = ParseDate("8:00pm december tenth");
211 if (! $date) {
212 # Error in the date
213 }
214
2152. Compare two dates
216
217 $date1 = ParseDate($string1);
218 $date2 = ParseDate($string2);
219 $flag = Date_Cmp($date1,$date2);
220 if ($flag<0) {
221 # date1 is earlier
222 } elsif ($flag==0) {
223 # the two dates are identical
224 } else {
225 # date2 is earlier
226 }
227
2283. Extract information from a date.
229
230 print &UnixDate("today","It is now %T on %b %e, %Y.");
231 => "It is now 13:24:08 on Feb 3, 1996."
232
2334. The amount of time between two dates.
234
235 $date1 = ParseDate($string1);
236 $date2 = ParseDate($string2);
237 $delta = DateCalc($date1,$date2,\$err);
238 => 0:0:WK:DD:HH:MM:SS the weeks, days, hours, minutes,
239 and seconds between the two
240 $delta = DateCalc($date1,$date2,\$err,1);
241 => YY:MM:WK:DD:HH:MM:SS the years, months, etc. between
242 the two
243
244 Read the documentation below for an explanation of the
245 difference.
246
2475. To determine a date a given offset from another.
248
249 $date = DateCalc("today","+ 3hours 12minutes 6 seconds",\$err);
250 $date = DateCalc("12 hours ago","12:30 6Jan90",\$err);
251
252 It even works with business days:
253
254 $date = DateCalc("today","+ 3 business days",\$err);
255
2566. To work with dates in another language.
257
258 &Date_Init("Language=French","DateFormat=non-US");
259 $date = ParseDate("1er decembre 1990");
260
2617. To find a list of dates where a recurring event happens
262 (including quite complex ones).
263
264 # To find the 2nd tuesday of every month
265 @date = ParseRecur("0:1*2:2:0:0:0",$base,$start,$stop);
266
267 # To find the Monday after easter in 1997-1999.
268 @date = ParseRecur("*1997-1999:0:0:0:0:0:0*EASTER,ND1");
269
270NOTE: Some date forms do not work as well in languages other than English,
271but this is not because Date::Manip is incapable of doing so (almost nothing
272in this module is language dependent). It is simply that I do not have the
273correct translation available for some words. If there is a date form that
274works in English but does not work in a language you need, let me know and
275if you can provide me the translation, I will fix Date::Manip.
276
277=head1 SHOULD I USE DATE::MANIP
278
279If you look in CPAN, you'll find that there are a number of Date and Time
280packages. Is Date::Manip the one you should be using? In my opinion, the
281answer is no most of the time. This sounds odd coming from the author of
282the software, but read on.
283
284Date::Manip is written entirely in perl. It's the most powerful of the
285date modules. It's also the biggest and slowest.
286
287Since Date::Manip is written entirely in perl, and depends on no other
288module not in a standard perl distribution, Date::Manip has no dependancies
289to meet. Other modules have dependancies on a C compiler or other perl
290modules. Since it is fairly easy to satisfy these dependancies for
291anyone who is reasonably familiar with perl modules, this is not a
292huge advantage that Date::Manip has.
293
294On the other hand, simpler perl modules tend to be faster than Date::Manip,
295and modules written in C are significantly faster than their perl
296counterparts (at least if they're done right). The TimeDate and
297Time-modules modules are written in perl, but are much simpler (and
298hence, faster) than Date::Manip. The Date::Calc module is written in C
299and is a good module for doing many date calculations much faster than
300Date::Manip. Between these three, most of your common date operations
301can be done.
302
303Date::Manip is certainly the most powerful of the Date modules. To the
304best of my knowledge, it will do everything that any other date module will
305do (not just the ones I listed above), and there are a number of features
306that Date::Manip has that none of the other modules have. Date::Manip is
307the "Swiss Army Knife" of Date modules. I'm trying to build a library
308which can do _EVERY_ conceivable date/time manipulation that you'll run
309into in everyday life.
310
311Although I am working on making Date::Manip faster, it will never be as
312fast as other modules. And before anyone asks, Date::Manip will never
313be translated to C (at least by me). I write C because I have to. I
314write perl because I like to. Date::Manip is something I do because it
315interests me, not something I'm paid for.
316
317Date::Manip is also big. The last time I looked, it's one of the largest
318CPAN modules there is. If you ignore modules like Tk, LWP, etc. which are
319actually packages of modules, it may be the largest. It's true that
320Date::Manip will do almost every date operation you could imagine... but
321you rarely need all that power. I'm working on reducing the footprint of
322Date::Manip, but even at it's slimmest, it'll outweigh the other modules by
323a good bit.
324
325If you are going to be using the module in cases where performance is an
326important factor (started up in a CGI program being run by your web server
3275,000 times a second), you should check out one of the other Date or Time
328modules in CPAN. If you're only doing fairly simple date operations
329(parsing common date formats, finding the difference between two dates,
330etc.), the other modules will almost certainly suffice. If you're doing
331one operation very repetitively (parsing 10,000 dates from a database), you
332are probably better off writing your own functions (perhaps bypassing all
333date modules entirely) designed specifically for your needs.
334
335On the other hand, if you want one solution for all your date needs, don't
336need peak speed, or are trying to do more exotic date operations,
337Date::Manip is for you. Operations on things like business dates, foreign
338language dates, holidays and other recurring events, etc. are available
339more-or-less exclusively in Date::Manip.
340
341=head1 ROUTINES
342
343=over 4
344
345=item ParseDate
346
347 $date = ParseDate(\@args);
348 $date = ParseDate($string);
349 $date = ParseDate(\$string);
350
351This takes an array or a string containing a date and parses it. When the
352date is included as an array (for example, the arguments to a program) the
353array should contain a valid date in the first one or more elements
354(elements after a valid date are ignored). Elements containing a valid
355date are shifted from the array. The largest possible number of elements
356which can be correctly interpreted as a valid date are always used. If a
357string is entered rather than an array, that string is tested for a valid
358date. The string is unmodified, even if passed in by reference.
359
360The real work is done in the ParseDateString routine.
361
362The ParseDate routine is primarily used to handle command line arguments.
363If you have a command where you want to enter a date as a command line
364argument, you can use Date::Manip to make something like the following
365work:
366
367 mycommand -date Dec 10 1997 -arg -arg2
368
369No more reading man pages to find out what date format is required in a
370man page.
371
372Historical note: this is originally why the Date::Manip routines were
373written (though long before they were released as the Date::Manip module).
374I was using a bunch of programs (primarily batch queue managers) where
375dates and times were entered as command line options and I was getting
376highly annoyed at the many different (but not compatible) ways that they
377had to be entered. Date::Manip originally consisted of basically 1 routine
378which I could pass "@ARGV" to and have it remove a date from the beginning.
379
380=item ParseDateString
381
382 $date = ParseDateString($string);
383
384This routine is called by ParseDate, but it may also be called directly
385to save some time (a negligable amount).
386
387NOTE: One of the most frequently asked questions that I have gotten
388is how to parse seconds since the epoch. ParseDateString cannot simply
389parse a number as the seconds since the epoch (it conflicts with some
390ISO-8601 date formats). There are two ways to get this information.
391First, you can do the following:
392
393 $secs = ... # seconds since Jan 1, 1970 00:00:00 GMT
394 $date = &DateCalc("Jan 1, 1970 00:00:00 GMT",$secs);
395
396Second, you can call it directly as:
397
398 $date = &ParseDateString("epoch $secs");
399
400To go backwards, just use the "%s" format of UnixDate:
401
402 $secs = &UnixDate($date,"%s");
403
404A full date actually includes 2 parts: date and time. A time must include
405hours and minutes and can optionally include seconds, fractional seconds,
406an am/pm type string, and a timezone. For example:
407
408 [at] HH:MN [Zone]
409 [at] HH:MN [am] [Zone]
410 [at] HH:MN:SS [am] [Zone]
411 [at] HH:MN:SS.SSSS [am] [Zone]
412 [at] HH am [Zone]
413
414Hours can be written using 1 or 2 digits, but the single digit form may
415only be used when no ambiguity is introduced (i.e. when it is not
416immediately preceded by a digit).
417
418A time is usually entered in 24 hour mode, but 12 hour mode can be used
419as well if AM/PM are entered (AM can be entered as AM or A.M. or other
420variations depending on the language).
421
422Fractional seconds are also supported in parsing but the fractional part is
423discarded (with NO rounding ocurring).
424
425Timezones always appear immediately after the time. A number of different
426forms are supported (see the section TIMEZONEs below).
427
428Incidentally, the time is removed from the date before the date is parsed,
429so the time may appear before or after the date, or between any two parts
430of the date.
431
432Valid date formats include the ISO 8601 formats:
433
434 YYYYMMDDHHMNSSF...
435 YYYYMMDDHHMNSS
436 YYYYMMDDHHMN
437 YYYYMMDDHH
438 YY-MMDDHHMNSSF...
439 YY-MMDDHHMNSS
440 YY-MMDDHHMN
441 YY-MMDDHH
442 YYYYMMDD
443 YYYYMM
444 YYYY
445 YY-MMDD
446 YY-MM
447 YY
448 YYYYwWWD ex. 1965-W02-2
449 YYwWWD
450 YYYYDOY ex. 1965-045
451 YYDOY
452
453In the above list, YYYY and YY signify 4 or 2 digit years, MM, DD, HH, MN, SS
454refer to two digit month, day, hour, minute, and second respectively. F...
455refers to fractional seconds (any number of digits) which will be ignored.
456The last 4 formats can be explained by example: 1965-w02-2 refers to Tuesday
457(day 2) of the 2nd week of 1965. 1965-045 refers to the 45th day of 1965.
458
459In all cases, parts of the date may be separated by dashes "-". If this is
460done, 1 or 2 digit forms of MM, DD, etc. may be used. All dashes are
461optional except for those given in the table above (which MUST be included
462for that format to be correctly parsed). So 19980820, 1998-0820,
4631998-08-20, 1998-8-20, and 199808-20 are all equivalent, but that date may
464NOT be written as 980820 (it must be written as 98-0820).
465
466NOTE: Even though not allowed in the standard, the timezone for an ISO-8601
467date is flexible and may be any of the timezones understood by Date::Manip.
468
469Additional date formats are available which may or may not be common including:
470
471 MM/DD **
472 MM/DD/YY **
473 MM/DD/YYYY **
474
475 mmmDD DDmmm mmmYYYY/DD mmmYYYY
476 mmmDD/YY DDmmmYY DD/YYmmm YYYYmmmDD YYYYmmm
477 mmmDDYYYY DDmmmYYYY DDYYYYmmm YYYY/DDmmm
478
479Where mmm refers to the name of a month. All parts of the date can be
480separated by valid separators (space, "/", or "."). The separator "-" may
481be used as long as it doesn't conflict with an ISO 8601 format, but this
482is discouraged since it is easy to overlook conflicts. For example, the
483format MM/DD/YY is just fine, but MM-DD-YY does not work since it conflicts
484with YY-MM-DD. To be safe, if "-" is used as a separator in a non-ISO
485format, they should be turned into "/" before calling the Date::Manip
486routines. As with ISO 8601 formats, all separators are optional except for
487those given as a "/" in the list above.
488
489** Note that with these formats, Americans tend to write month first, but
490many other countries tend to write day first. The latter behavior can be
491obtained by setting the config variable DateFormat to something other than
492"US" (see CUSTOMIZING DATE::MANIP below).
493
494Date separators are treated very flexibly (they are converted to spaces),
495so the following dates are all equivalent:
496
497 12/10/1965
498 12-10 / 1965
499 12 // 10 -. 1965
500
501In some cases, this may actually be TOO flexible, but no attempt is made to
502trap this.
503
504Years can be entered as 2 or 4 digits, days and months as 1 or 2 digits.
505Both days and months must include 2 digits whenever they are immediately
506adjacent to another numeric part of the date or time. Date separators
507are required if single digit forms of DD or MM are used. If separators
508are not used, the date will either be unparsable or will get parsed
509incorrectly.
510
511Miscellaneous other allowed formats are:
512 which dofw in mmm in YY "first sunday in june 1996 at 14:00" **
513 dofw week num YY "sunday week 22 1995" **
514 which dofw YY "22nd sunday at noon" **
515 dofw which week YY "sunday 22nd week in 1996" **
516 next/last dofw "next friday at noon"
517 next/last week/month "next month"
518 in num days/weeks/months "in 3 weeks at 12:00"
519 num days/weeks/months later "3 weeks later"
520 num days/weeks/months ago "3 weeks ago"
521 dofw in num week "Friday in 2 weeks"
522 in num weeks dofw "in 2 weeks on friday"
523 dofw num week ago "Friday 2 weeks ago"
524 num week ago dofw "2 weeks ago friday"
525 last day in mmm in YY "last day of October"
526 dofw "Friday" (Friday of current week)
527 Nth "12th", "1st" (day of current month)
528 epoch SECS seconds since the epoch (negative values
529 are supported)
530
531** Note that the formats "sunday week 22" and "22nd sunday" give very
532different bahaviors. "sunday week 22" returns the sunday of the 22nd week
533of the year based on how week 1 is defined. ISO 8601 defines week one to
534contain Jan 4, so "sunday week 1" might be the first or second sunday of
535the current year, or the last sunday of the previous year. "22nd sunday"
536gives the actual 22nd time sunday occurs in a given year, regardless of the
537definition of a week.
538
539Note that certain words such as "in", "at", "of", etc. which commonly appear
540in a date or time are ignored. Also, the year is always optional.
541
542In addition, the following strings are recognized:
543 today (exactly now OR today at a given time if a time is specified)
544 now (synonym for today)
545 yesterday (exactly 24 hours ago unless a time is specified)
546 tomorrow (exactly 24 hours from now unless a time is specifed)
547 noon (12:00:00)
548 midnight (00:00:00)
549Other languages have similar (and in some cases additional) strings.
550
551Some things to note:
552
553All strings are case insensitive. "December" and "DEceMBer" both work.
554
555When a part of the date is not given, defaults are used: year defaults
556to current year; hours, minutes, seconds to 00.
557
558The year may be entered as 2 or 4 digits. If entered as 2 digits, it will
559be converted to a 4 digit year. There are several ways to do this based on
560the value of the YYtoYYYY variable (described below). The default behavior
561it to force the 2 digit year to be in the 100 year period CurrYear-89 to
562CurrYear+10. So in 1996, the range is [1907 to 2006], and the 2 digit year
56305 would refer to 2005 but 07 would refer to 1907. See CUSTOMIZING
564DATE::MANIP below for information on YYtoYYYY for other methods.
565
566Dates are always checked to make sure they are valid.
567
568In all of the formats, the day of week ("Friday") can be entered anywhere
569in the date and it will be checked for accuracy. In other words,
570 "Tue Jul 16 1996 13:17:00"
571will work but
572 "Jul 16 1996 Wednesday 13:17:00"
573will not (because Jul 16, 1996 is Tuesday, not Wednesday). Note that
574depending on where the weekday comes, it may give unexpected results when
575used in array context (with ParseDate). For example, the date
576("Jun","25","Sun","1990") would return June 25 of the current year since
577Jun 25, 1990 is not Sunday.
578
579The times "12:00 am", "12:00 pm", and "midnight" are not well defined. For
580good or bad, I use the following convention in Date::Manip:
581 midnight = 12:00am = 00:00:00
582 noon = 12:00pm = 12:00:00
583and the day goes from 00:00:00 to 23:59:59. In other words, midnight is the
584beginning of a day rather than the end of one. The time 24:00:00 is also
585allowed (though it is automatically transformed to 00:00:00 of the following
586day).
587
588The format of the date returned is YYYYMMDDHH:MM:SS. The advantage of this
589time format is that two times can be compared using simple string comparisons
590to find out which is later. Also, it is readily understood by a human.
591Alternate forms can be used if that is more convenient. See Date_Init below
592and the config variable Internal.
593
594NOTE: The format for the date is going to change at some point in the future
595to YYYYMMDDHH:MN:SS+HHMN*FLAGS. In order to maintain compatibility, you
596should use UnixDate to extract information from a date, and Date_Cmp to compare
597two dates. The simple string comparison will only work for dates in the same
598timezone.
599
600=item UnixDate
601
602 @date = UnixDate($date,@format);
603 $date = UnixDate($date,@format);
604
605This takes a date and a list of strings containing formats roughly
606identical to the format strings used by the UNIX date(1) command. Each
607format is parsed and an array of strings corresponding to each format is
608returned.
609
610$date may be any string that can be parsed by ParseDateString.
611
612The format options are:
613
614 Year
615 %y year - 00 to 99
616 %Y year - 0001 to 9999
617 %G year - 0001 to 9999 (see below)
618 %L year - 0001 to 9999 (see below)
619 Month, Week
620 %m month of year - 01 to 12
621 %f month of year - " 1" to "12"
622 %b,%h month abbreviation - Jan to Dec
623 %B month name - January to December
624 %U week of year, Sunday
625 as first day of week - 01 to 53
626 %W week of year, Monday
627 as first day of week - 01 to 53
628 Day
629 %j day of the year - 001 to 366
630 %d day of month - 01 to 31
631
632 %e day of month - " 1" to "31"
633 %v weekday abbreviation - " S"," M"," T"," W","Th"," F","Sa"
634 %a weekday abbreviation - Sun to Sat
635 %A weekday name - Sunday to Saturday
636 %w day of week - 1 (Monday) to 7 (Sunday)
637 %E day of month with suffix - 1st, 2nd, 3rd...
638 Hour
639 %H hour - 00 to 23
640 %k hour - " 0" to "23"
641 %i hour - " 1" to "12"
642 %I hour - 01 to 12
643 %p AM or PM
644 Minute, Second, Timezone
645 %M minute - 00 to 59
646 %S second - 00 to 59
647 %s seconds from 1/1/1970 GMT- negative if before 1/1/1970
648 %o seconds from Jan 1, 1970
649 in the current time zone
650 %Z timezone - "EDT"
651 %z timezone as GMT offset - "+0100"
652 Date, Time
653 %c %a %b %e %H:%M:%S %Y - Fri Apr 28 17:23:15 1995
654 %C,%u %a %b %e %H:%M:%S %z %Y - Fri Apr 28 17:25:57 EDT 1995
655 %g %a, %d %b %Y %H:%M:%S %z - Fri, 28 Apr 1995 17:23:15 EDT
656 %D,%x %m/%d/%y - 04/28/95
657 %l date in ls(1) format
658 %b %e $H:$M - Apr 28 17:23 (if within 6 months)
659 %b %e %Y - Apr 28 1993 (otherwise)
660 %r %I:%M:%S %p - 05:39:55 PM
661 %R %H:%M - 17:40
662 %T,%X %H:%M:%S - 17:40:58
663 %V %m%d%H%M%y - 0428174095
664 %Q %Y%m%d - 19961025
665 %q %Y%m%d%H%M%S - 19961025174058
666 %P %Y%m%d%H%M%S - 1996102517:40:58
667 %F %A, %B %e, %Y - Sunday, January 1, 1996
668 %J %G-W%W-%w - 1997-W02-2
669 %K %Y-%j - 1997-045
670 Other formats
671 %n insert a newline character
672 %t insert a tab character
673 %% insert a `%' character
674 %+ insert a `+' character
675 The following formats are currently unused but may be used in the future:
676 NO 1234567890 !@#$^&*()_|-=\`[];',./~{}:<>?
677 They currently insert the character following the %, but may (and probably
678 will) change in the future as new formats are added.
679
680If a lone percent is the final character in a format, it is ignored.
681
682Note that the ls format (%l) applies to date within the past OR future 6
683months!
684
685The %U, %W, %L, and %G formats are used to support the ISO-8601 format:
686YYYY-wWW-D. In this format, a date is written as a year, the week of
687the year, and the day of the week. Technically, the week may be considered
688to start on any day of the week, but Sunday and Monday are the two most
689common choices, so both are supported.
690
691The %U and %W formats return a week-of-year number from 01 to 53, and
692%L and %G return a 4-digit year corresponding to the week. Most of the
693time, the %L and %G formats returns the same value as the %Y format,
694but there is a problem with days occuring in the first or last week of
695the year.
696
697The ISO-8601 representation of Jan 1, 1993 written in the YYYY-wWWW-D
698format is actually 1992-W53-5. In other words, Jan 1 is treates as being
699in the last week of the preceding year. Depending on the year, days in
700the first week of a year may belong to the previous year, and days in the
701final week of a year may belong to the next year.
702
703The %L and %U formats contains the year and week-of-year values treating
704weeks as starting on Sunday. The %G and %W formats are the year and
705week-of-year values treating weeks as starting on Monday.
706
707%J returns the full ISO-8601 format (%G-W%W-%w).
708
709The formats used in this routine were originally based on date.pl (version
7103.2) by Terry McGonigal, as well as a couple taken from different versions
711of the Solaris date(1) command. Also, several have been added which are
712unique to Date::Manip.
713
714=item ParseDateDelta
715
716 $delta = ParseDateDelta(\@args);
717 $delta = ParseDateDelta($string);
718 $delta = ParseDateDelta(\$string);
719
720This takes an array and shifts a valid delta date (an amount of time)
721from the array. Recognized deltas are of the form:
722 +Yy +Mm +Ww +Dd +Hh +MNmn +Ss
723 examples:
724 +4 hours +3mn -2second
725 + 4 hr 3 minutes -2
726 4 hour + 3 min -2 s
727 +Y:+M:+W:+D:+H:+MN:+S
728 examples:
729 0:0:0:0:4:3:-2
730 +4:3:-2
731 mixed format
732 examples:
733 4 hour 3:-2
734
735A field in the format +Yy is a sign, a number, and a string specifying
736the type of field. The sign is "+", "-", or absent (defaults to the
737next larger element). The valid strings specifying the field type
738are:
739 y: y, yr, year, years
740 m: m, mon, month, months
741 w: w, wk, ws, wks, week, weeks
742 d: d, day, days
743 h: h, hr, hour, hours
744 mn: mn, min, minute, minutes
745 s: s, sec, second, seconds
746
747Also, the "s" string may be omitted. The sign, number, and string may
748all be separated from each other by any number of whitespaces.
749
750In the date, all fields must be given in the order: Y M W D H MN S. Any
751number of them may be omitted provided the rest remain in the correct
752order. In the 2nd (colon) format, from 2 to 7 of the fields may be given.
753For example +D:+H:+MN:+S may be given to specify only four of the fields.
754In any case, both the MN and S field may be present. No spaces may be
755present in the colon format.
756
757Deltas may also be given as a combination of the two formats. For example,
758the following is valid: +Yy +D:+H:+MN:+S. Again, all fields must be given
759in the correct order.
760
761The word "in" may be given (prepended in English) to the delta ("in 5 years")
762and the word "ago" may be given (appended in English) ("6 months ago"). The
763"in" is completely ignored. The "ago" has the affect of reversing all signs
764that appear in front of the components of the delta. I.e. "-12 yr 6 mon ago"
765is identical to "+12yr +6mon" (don't forget that there is an implied minus
766sign in front of the 6 because when no sign is explicitly given, it carries
767the previously entered sign).
768
769One thing is worth noting. The year/month and day/hour/min/sec parts are
770returned in a "normalized" form. That is, the signs are adjusted so as to
771be all positive or all negative. For example, "+ 2 day - 2hour" does not
772return "0:0:0:2:-2:0:0". It returns "+0:0:0:1:22:0:0" (1 day 22 hours
773which is equivalent). I find (and I think most others agree) that this is
774a more useful form.
775
776Since the year/month and day/hour/min/sec parts must be normalized
777separately there is the possibility that the sign of the two parts will be
778different. So, the delta "+ 2years -10 months - 2 days + 2 hours" produces
779the delta "+1:2:-0:1:22:0:0".
780
781It is possible to include a sign for all elements that is output. See the
782configuration variable DeltaSigns below.
783
784NOTE: The internal format of the delta changed in version 5.30 from
785Y:M:D:H:MN:S to Y:M:W:D:H:MN:S . Also, it is going to change again at some
786point in the future to Y:M:W:D:H:MN:S*FLAGS . Use the routine Delta_Format
787to extract information rather than parsing it yourself.
788
789=item Delta_Format
790
791 @str = Delta_Format($delta,$dec,@format);
792 $str = Delta_Format($delta,$dec,@format);
793
794This is similar to the UnixDate routine except that it extracts information
795from a delta. Unlike the UnixDate routine, most of the formats are 2
796characters instead of 1.
797
798Formats currently understood are:
799
800 %Xv : the value of the field named X
801 %Xd : the value of the field X, and all smaller fields, expressed in
802 units of X
803 %Xh : the value of field X, and all larger fields, expressed in units
804 of X
805 %Xt : the value of all fields expressed in units of X
806
807 X is one of y,M,w,d,h,m,s (case sensitive).
808
809 %% : returns a "%"
810
811NOTE: Delta_Format only understands "exact" relationships, so for any delta
812that has a month component, there can be no mixing of the Y/M and
813W/D/H/MN/S segments. In other words, the delta 1:6:1:1:1:1:1 has a month
814component, so asking for the total number of years (using the %yd format)
815will return 1.5 (which is what 1 year 6 months is). For deltas which have
816NO month component, the relationship between years and days is known
817(365.25 is used) and all formats work as expected (except that formats with
818X equal to "M" are not allowed).
819
820So, the format "%hd" means the values of H, MN, and S expressed in hours.
821So for the delta "0:0:0:0:2:30:0", this format returns 2.5. Similarly, the
822format "%yd" means the value (in years) of both the Y and M fields, or,
823if the month component is 0, it uses Y, W, D, H, MN, S.
824
825The format "%hh" returns the value of W, D, and H expressed in hours if
826the month component is non-zero, or Y, W, D, H if the month component is 0.
827
828If $dec is non-zero, the %Xd and %Xt values are formatted to contain $dec
829decimal places.
830
831=item ParseRecur
832
833 $recur = ParseRecur($string [,$base,$date0,$date1,$flags]);
834 @dates = ParseRecur($string [,$base,$date0,$date1,$flags]);
835
836A recurrence refers to a recurring event. A fully specified recurrence
837requires (in most cases) 4 items: a recur description (describing the
838frequency of the event), a base date (a date when the event occurred and
839which other occurrences are based on), and a start and end date. There may
840be one or more flags included which modify the behavior of the recur
841description. The fully specified recurrence is written as:
842
843 recur*flags*base*date0*date1
844
845Here, base, date0, and date1 are any strings (which must not contain any
846asterixes) which can be parsed by ParseDate. flags is a comma separated
847list of flags (described below), and recur is a string describing a
848recurring event.
849
850If called in scalar context, it returns a string containing a fully
851specified recurrence (or as much of it as can be determined with
852unspecified fields left blank). In list context, it returns a list of all
853dates referred to by a recurrence if enough information is given in the
854recurrence. All dates returned are in the range:
855
856 date0 <= date < date1
857
858The argument $string can contain any of the parts of a full recurrence.
859For example:
860
861 recur
862 recur*flags
863 recur**base*date0*date1
864
865The only part which is required is the recur description. Any values
866contained in $string are overridden or modified by values passed in as
867parameters to ParseRecur.
868
869A recur description is a string of the format Y:M:W:D:H:MN:S . Exactly one
870of the colons may optionally be replaced by an asterisk, or an asterisk may
871be prepended to the string.
872
873Any value "N" to the left of the asterisk refers to the "Nth" one. Any
874value to the right of the asterisk refers to a value as it appears on a
875calendar/clock. Values to the right can be listed a single values, ranges
876(2 numbers separated by a dash "-"), or a comma separated list of values
877or ranges. In a few cases, negative values are appropriate.
878
879This is best illustrated by example.
880
881 0:0:2:1:0:0:0 every 2 weeks and 1 day
882 0:0:0:0:5:30:0 every 5 hours and 30 minutes
883 0:0:0:2*12:30:0 every 2 days at 12:30 (each day)
884 3*1:0:2:12:0:0 every 3 years on Jan 2 at noon
885 0:1*0:2:12,14:0:0 2nd of every month at 12:00 and 14:00
886 1:0:0*45:0:0:0 45th day of every year
887 0:1*4:2:0:0:0 4th tuesday (day 2) of every month
888 0:1*-1:2:0:0:0 last tuesday of every month
889 0:1:0*-2:0:0:0 2nd to last day of every month
890 0:0:3*2:0:0:0 every 3rd tuesday (every 3 weeks on 2nd day of week)
891 1:0*12:2:0:0:0 tuesday of the 12th week of each year
892 *1990-1995:12:0:1:0:0:0
893 Dec 1 in 1990 through 1995
894
895 0:1*2:0:0:0:0 the start of the 2nd week of every month (see Note 2)
896 1*1:2:0:0:0:0 the start of the 2nd week in January each year (Note 2)
897
898I realize that this looks a bit cryptic, but after a discussion on the
899CALENDAR mailing list, it looked like there was no concise, flexible
900notation for handling recurring events. ISO 8601 notations were very bulky
901and lacked the flexibility I wanted. As a result, I developed this
902notation (based on crontab formats, but with much more flexibility) which
903fits in well with this module, and which is able to express every type of
904recurring event I could think of.
905
906NOTE: If a recurrence has a date0 and date1 in it AND a date0 and date1
907are passed in to the function, both sets of criteria apply. If flags are
908passed in, they override any flags in the recurrence UNLESS the flags
909passed in start with a plus (+) character in which case they are appended
910to the flags in the recurrence.
911
912NOTE: There is no way to express the following with a single recurrence:
913
914 every day at 12:30 and 1:00
915
916You have to use two recurrences to do this.
917
918NOTE: A recurrence specifying the week of a month is NOT clearly defined
919in common usage. What is the 1st week in a month? The behavior (with
920respect to this module) is well defined (using the FDn and FIn flags
921below), but in common usage, this is so ambiguous that this form should
922probably never be used. It is included here solely for the sake of
923completeness.
924
925NOTE: Depending on whether M and W are 0 or nonzero, D means different
926things. This is given in the following table.
927
928 M W D (when right of an asterisk) refers to
929 - - -------------------------------------------
930 0 0 day of year (1-366)
931 M 0 day of month (1-31)
932 0 W day of week (1-7), W refers to the week of year
933 M W the Wth (1-5 or -1 to -5) occurrence of Dth (1-7) day of week in month
934
935NOTE: Base dates are only used with some types of recurrences. For example,
936
937 0:0:3*2:0:0:0 every 3rd tuesday
938
939requires a base date. If a base date is specified which doesn't match the
940criteria (for example, if a base date falling on Monday were passed in with
941this recurrence), the base date is moved forward to the first relevant date.
942
943Other dates do not require a base date. For example:
944
945 0:0*3:2:0:0:0 third tuesday of every month
946
947A recurrence written in the above format does NOT provide default values
948for base, date0, or date1. They must be specified in order to get a list
949of dates.
950
951A base date is not used entirely. It is only used to provide the parts
952necessary for the left part of a recurrence. For example, the recurrence:
953
954 1:3*0:4:0:0:0 every 1 year, 3 months on the 4th day of the month
955
956would only use the year and month of the base date.
957
958
959There are a small handful of English strings which can be parsed in place
960of a numerical recur description. These include:
961
962 every 2nd day [in 1997]
963 every 2nd day in June [1997]
964 2nd day of every month [in 1997]
965 2nd tuesday of every month [in 1997]
966 last tuesday of every month [in 1997]
967 every tuesday [in 1997]
968 every 2nd tuesday [in 1997]
969 every 2nd tuesday in June [1997]
970
971Each of these set base, date0, and date1 to a default value (the current
972year with Jan 1 being the base date is the default if the year and month
973are missing).
974
975The following flags (case insensitive) are understood:
976
977 MWn : n is 1-7. The first week of the month is the week
978 which contains the first occurrence of day n (1=Monday).
979 MW2 means that the first week contains the first Tuesday
980 of the month.
981 MDn : n is 1-7. The first week of the month contains the
982 actual date (1st through 7th). MD4 means that the first
983 week of the month contains the 4th of that month.
984
985 PDn : n is 1-7. Means the previous day n not counting today
986 PTn : n is 1-7. Means the previous day n counting today
987 NDn : n is 1-7. Means the next day n not counting today
988 NTn : n is 1-7. Means the next day n counting today
989
990 FDn : n is any number. Means step forward n days.
991 BDn : n is any number. Means step backward n days.
992 FWn : n is any number. Means step forward n workdays.
993 BWn : n is any number. Means step backward n workdays.
994
995 CWD : the closest work day (using the TomorrowFirst config variable).
996 CWN : the closest work day (looking forward first).
997 CWP : the closest work day (looking backward first).
998
999 NWD : next work day counting today
1000 PWD : previous work day counting today
1001 DWD : next/previous work day (TomorrowFirst config) counting today
1002
1003 EASTER: select easter for this year (the M, W, D fields are ignored
1004 in the recur).
1005
1006NOTE: only one of MWn and MDn can be set. If both are set, only the
1007last one is used. The default is MW7 (i.e. the first week contains
1008the first Sunday).
1009
1010CWD, CWN, and CWP will usually return the same value, but if you are
1011starting at the middle day of a 3-day weekend (for example), it will return
1012either the first work day of the following week, or the last work day of
1013the previous week depending on whether it looks forward or backward first.
1014
1015All flags are applied AFTER the recurrence dates are calculated, and they
1016may move a date outside of the date0 to date1 range. No check is made for
1017this.
1018
1019The workday flags do not act exactly the same as a business mode calculation.
1020For example, a date that is Saturday with a FW1 steps forward to the first
1021workday (i.e. Monday).
1022
1023=item Date_Cmp
1024
1025 $flag = Date_Cmp($date1,$date2);
1026
1027This takes two dates and compares them. Almost all dates can be compared
1028using the perl "cmp" command. The only time this will not work is when
1029comparing dates in different timezones. This routine will take that into
1030account.
1031
1032NOTE: This routine currently does little more than use "cmp", but once
1033the internal format for storing dates is in place (where timezone information
1034is kept as part of the date), this routine will become more important. You
1035should use this routine in prepartation for that version.
1036
1037=item DateCalc
1038
1039 $d = DateCalc($d1,$d2 [,\$err] [,$mode]);
1040
1041This takes two dates, deltas, or one of each and performs the appropriate
1042calculation with them. Dates must be a string that can be parsed by
1043&ParseDateString. Deltas must be a string that can be parsed by
1044&ParseDateDelta. Two deltas add together to form a third delta. A date
1045and a delta returns a 2nd date. Two dates return a delta (the difference
1046between the two dates).
1047
1048Note that in many cases, it is somewhat ambiguous what the delta actually
1049refers to. Although it is ALWAYS known how many months in a year, hours in
1050a day, etc., it is NOT known how many days form a month. As a result, the
1051part of the delta containing month/year and the part with sec/min/hr/day
1052must be treated separately. For example, "Mar 31, 12:00:00" plus a delta
1053of 1month 2days would yield "May 2 12:00:00". The year/month is first
1054handled while keeping the same date. Mar 31 plus one month is Apr 31 (but
1055since Apr only has 30 days, it becomes Apr 30). Apr 30 + 2 days is May 2.
1056As a result, in the case where two dates are entered, the resulting delta
1057can take on two different forms. By default ($mode=0), an absolutely
1058correct delta (ignoring daylight savings time) is returned in days, hours,
1059minutes, and seconds.
1060
1061If $mode is 1, the math is done using an approximate mode where a delta is
1062returned using years and months as well. The year and month part is
1063calculated first followed by the rest. For example, the two dates "Mar 12
10641995" and "Apr 13 1995" would have an exact delta of "31 days" but in the
1065approximate mode, it would be returned as "1 month 1 day". Also, "Mar 31"
1066and "Apr 30" would have deltas of "30 days" or "1 month" (since Apr 31
1067doesn't exist, it drops down to Apr 30). Approximate mode is a more human
1068way of looking at things (you'd say 1 month and 2 days more often then 33
1069days), but it is less meaningful in terms of absolute time. In approximate
1070mode $d1 and $d2 must be dates. If either or both is a delta, the
1071calculation is done in exact mode.
1072
1073If $mode is 2, a business mode is used. That is, the calculation is done
1074using business days, ignoring holidays, weekends, etc. In order to
1075correctly use this mode, a config file must exist which contains the
1076section defining holidays (see documentation on the config file below).
1077The config file can also define the work week and the hours of the work
1078day, so it is possible to have different config files for different
1079businesses.
1080
1081For example, if a config file defines the workday as 08:00 to 18:00, a
1082work week consisting of Mon-Sat, and the standard (American) holidays, then
1083from Tuesday at 12:00 to the following Monday at 14:00 is 5 days and 2
1084hours. If the "end" of the day is reached in a calculation, it
1085automatically switches to the next day. So, Tuesday at 12:00 plus 6 hours
1086is Wednesday at 08:00 (provided Wed is not a holiday). Also, a date that
1087is not during a workday automatically becomes the start of the next
1088workday. So, Sunday 12:00 and Monday at 03:00 both automatically becomes
1089Monday at 08:00 (provided Monday is not a holiday). In business mode, any
1090combination of date and delta may be entered, but a delta should not
1091contain a year or month field (weeks are fine though).
1092
1093See below for some additional comments about business mode calculations.
1094
1095Note that a business week is treated the same as an exact week (i.e. from
1096Tuesday to Tuesday, regardless of holidays). Because this means that the
1097relationship between days and weeks is NOT unambiguous, when a delta is
1098produced from two dates, it will be in terms of d/h/mn/s (i.e. no week
1099field).
1100
1101If $mode is 3 (which only applies when two dates are passed in), an exact
1102business mode is used. In this case, it returns a delta as an exact number
1103of business days/hours/etc. between the two. Weeks, months, and years are
1104ignored.
1105
1106Any other non-nil value of $mode is treated as $mode=1 (approximate mode).
1107
1108The mode can be automatically set in the dates/deltas passed by including a
1109key word somewhere in it. For example, in English, if the word
1110"approximately" is found in either of the date/delta arguments, approximate
1111mode is forced. Likewise, if the word "business" or "exactly" appears,
1112business/exact mode is forced (and $mode is ignored). So, the two
1113following are equivalent:
1114
1115 $date = DateCalc("today","+ 2 business days",\$err);
1116 $date = DateCalc("today","+ 2 days",\$err,2);
1117
1118Note that if the keyword method is used instead of passing in $mode, it is
1119important that the keyword actually appear in the argument passed in to
1120DateCalc. The following will NOT work:
1121
1122 $delta = ParseDateDelta("+ 2 business days");
1123 $today = ParseDate("today");
1124 $date = DateCalc($today,$delta,\$err);
1125
1126because the mode keyword is removed from a date/delta by the parse routines,
1127and the mode is reset each time a parse routine is called. Since DateCalc
1128parses both of its arguments, whatever mode was previously set is ignored.
1129
1130If \$err is passed in, it is set to:
1131 1 is returned if $d1 is not a delta or date
1132 2 is returned if $d2 is not a delta or date
1133 3 is returned if the date is outside the years 1000 to 9999
1134This argument is optional, but if included, it must come before $mode.
1135
1136Nothing is returned if an error occurs.
1137
1138When a delta is returned, the signs such that it is strictly positive or
1139strictly negative ("1 day - 2 hours" would never be returned for example).
1140The only time when this cannot be enforced is when two deltas with a
1141year/month component are entered. In this case, only the signs on the
1142day/hour/min/sec part are standardized.
1143
1144=item Date_SetTime
1145
1146 $date = Date_SetTime($date,$hr,$min,$sec);
1147 $date = Date_SetTime($date,$time);
1148
1149This takes a date (any string that may be parsed by ParseDateString) and
1150sets the time in that date. For example, one way to get the time for 7:30
1151tomorrow would be to use the lines:
1152
1153 $date = ParseDate("tomorrow");
1154 $date = Date_SetTime($date,"7:30");
1155
1156Note that in this routine (as well as the other routines below which use
1157a time argument), no real parsing is done on the times. As a result,
1158
1159 $date = Date_SetTime($date,"13:30");
1160
1161works, but
1162
1163 $date = Date_SetTime($date,"1:30 PM");
1164
1165doesn't.
1166
1167=item Date_SetDateField
1168
1169 $date = Date_SetDateField($date,$field,$val [,$nocheck]);
1170
1171This takes a date and sets one of it's fields to a new value. $field is
1172any of the strings "y", "m", "d", "h", "mn", "s" (case insensitive) and
1173$val is the new value.
1174
1175If $nocheck is non-zero, no check is made as to the validity of the date.
1176
1177=item Date_GetPrev
1178
1179 $date = Date_GetPrev($date,$dow, $curr [,$hr,$min,$sec]);
1180 $date = Date_GetPrev($date,$dow, $curr [,$time]);
1181 $date = Date_GetPrev($date,undef,$curr,$hr,$min,$sec);
1182 $date = Date_GetPrev($date,undef,$curr,$time);
1183
1184This takes a date (any string that may be parsed by ParseDateString) and finds
1185the previous occurrence of either a day of the week, or a certain time of day.
1186
1187If $dow is defined, the previous occurrence of the day of week is returned.
1188$dow may either be a string (such as "Fri" or "Friday") or a number
1189(between 1 and 7). The date of the previous $dow is returned.
1190
1191If $date falls on the day of week given by $dow, the date returned depends
1192on $curr. If $curr is 0, the date returned is a week before $date. If
1193$curr is 1, the date returned is the same as $date. If $curr is 2, the date
1194returned (including the time information) is required to be before $date.
1195
1196If a time is passed in (either as separate hours, minutes, seconds or as a
1197time in HH:MM:SS or HH:MM format), the time on this date is set to it. The
1198following examples should illustrate the use of Date_GetPrev:
1199
1200 date dow curr time returns
1201 Fri Nov 22 18:15:00 Thu any 12:30 Thu Nov 21 12:30:00
1202 Fri Nov 22 18:15:00 Fri 0 12:30 Fri Nov 15 12:30:00
1203 Fri Nov 22 18:15:00 Fri 1/2 12:30 Fri Nov 22 12:30:00
1204
1205 Fri Nov 22 18:15:00 Fri 1 18:30 Fri Nov 22 18:30:00
1206 Fri Nov 22 18:15:00 Fri 2 18:30 Fri Nov 15 18:30:00
1207
1208If $dow is undefined, then a time must be entered, and the date returned is
1209the previous occurrence of this time. If $curr is non-zero, the current
1210time is returned if it matches the criteria passed in. In other words, the
1211time returned is the last time that a digital clock (in 24 hour mode) would
1212have displayed the time you passed in. If you define hours, minutes and
1213seconds default to 0 and you might jump back as much as an entire day. If
1214hours are undefined, you are looking for the last time the minutes/seconds
1215appeared on the digital clock, so at most, the time will jump back one hour.
1216
1217 date curr hr min sec returns
1218 Nov 22 18:15:00 0/1 18 undef undef Nov 22 18:00:00
1219 Nov 22 18:15:00 0/1 18 30 0 Nov 21 18:30:00
1220 Nov 22 18:15:00 0 18 15 undef Nov 21 18:15:00
1221 Nov 22 18:15:00 1 18 15 undef Nov 22 18:15:00
1222 Nov 22 18:15:00 0 undef 15 undef Nov 22 17:15:00
1223 Nov 22 18:15:00 1 undef 15 undef Nov 22 18:15:00
1224
1225=item Date_GetNext
1226
1227 $date = Date_GetNext($date,$dow, $curr [,$hr,$min,$sec]);
1228 $date = Date_GetNext($date,$dow, $curr [,$time]);
1229 $date = Date_GetNext($date,undef,$curr,$hr,$min,$sec);
1230 $date = Date_GetNext($date,undef,$curr,$time);
1231
1232Similar to Date_GetPrev.
1233
1234=item Date_IsHoliday
1235
1236 $name = Date_IsHoliday($date);
1237
1238This returns undef if $date is not a holiday, or a string containing the
1239name of the holiday otherwise. An empty string is returned for an unnamed
1240holiday.
1241
1242=item Events_List
1243
1244 $ref = Events_List($date);
1245 $ref = Events_List($date ,0 [,$flag]);
1246 $ref = Events_List($date0,$date1 [,$flag]);
1247
1248This returns a list of events. Events are defined in the Events section
1249of the config file (discussed below).
1250
1251In the first form (a single argument), $date is any string containing a
1252date. A list of events active at that precise time will be returned.
1253The format is similar to when $flag=0, except only a single time will
1254be returned.
1255
1256In all other cases, a range of times will be used. If the 2nd argument
1257evaluates to 0, the range of times will be the 24 hour period from
1258midnight to midnight containing $date. Otherwise, the range is given
1259by the two dates.
1260
1261The value of $flag determines the format of the information that is
1262returned.
1263
1264With $flag=0, the events are returned as a reference to a list of the form:
1265
1266 [ date, [ list_of_events ], date, [ list_of_events ], ... ]
1267
1268For example, if the following events are defined (using the syntax
1269discussed below in the description of the Event section of the config
1270file):
1271
1272 2000-01-01 ; 2000-03-21 = Winter
1273 2000-03-22 ; 2000-06-21 = Spring
1274 2000-02-01 = Event1
1275 2000-05-01 = Event2
1276 2000-04-01-12:00:00 = Event3
1277
1278might result in the following output:
1279
1280 &Events_List("2000-04-01")
1281 => [ 2000040100:00:00, [ Spring ] ]
1282
1283 &Events_List("2000-04-01 12:30");
1284 => [ 2000040112:30:00, [ Spring, Event3 ] ]
1285
1286 &Events_List("2000-04-01",0);
1287 => [ 2000040100:00:00, [ Spring ],
1288 2000040112:00:00, [ Spring, Event3 ],
1289 2000040113:00:00, [ Spring ] ]
1290
1291 &Events_List("2000-03-15","2000-04-10");
1292 => [ 2000031500:00:00, [ Winter ],
1293 2000032200:00:00, [ Spring ]
1294 2000040112:00:00, [ Spring, Event3 ]
1295 2000040113:00:00, [ Spring ] ]
1296
1297Much more complicated events can be defined using recurrences.
1298
1299When $flag is non-zero, the format of the output is changed. If $flag
1300is 1, then a tally of the amount of time given to each event is returned.
1301Time for which two or more events apply is counted for both.
1302
1303 &Events_List("2000-03-15","2000-04-10",1);
1304 => { Winter => +0:0:1:0:0:0:0,
1305 Spring => +0:0:2:5:0:0:0,
1306 Event3 => +0:0:0:0:1:0:0 }
1307
1308When $flag is 2, a more complex tally with no event counted twice is
1309returned.
1310
1311 &Events_List("2000-03-15","2000-04-10",2);
1312 => { Winter => +0:0:1:0:0:0:0,
1313 Spring => +0:0:2:4:23:0:0,
1314 Event3+Spring => +0:0:0:0:1:0:0 }
1315
1316The hash contains one element for each combination of events.
1317
1318=item Date_DayOfWeek
1319
1320 $day = Date_DayOfWeek($m,$d,$y);
1321
1322Returns the day of the week (1 for Monday, 7 for Sunday).
1323
1324All arguments must be numeric.
1325
1326=item Date_SecsSince1970
1327
1328 $secs = Date_SecsSince1970($m,$d,$y,$h,$mn,$s);
1329
1330Returns the number of seconds since Jan 1, 1970 00:00 (negative if date is
1331earlier).
1332
1333All arguments must be numeric.
1334
1335=item Date_SecsSince1970GMT
1336
1337 $secs = Date_SecsSince1970GMT($m,$d,$y,$h,$mn,$s);
1338
1339Returns the number of seconds since Jan 1, 1970 00:00 GMT (negative if date
1340is earlier). If CurrTZ is "IGNORE", the number will be identical to
1341Date_SecsSince1970 (i.e. the date given will be treated as being in GMT).
1342
1343All arguments must be numeric.
1344
1345=item Date_DaysSince1BC
1346
1347 $days = Date_DaysSince1BC($m,$d,$y);
1348
1349Returns the number of days since Dec 31, 1BC. This includes the year 0000.
1350
1351All arguments must be numeric.
1352
1353=item Date_DayOfYear
1354
1355 $day = Date_DayOfYear($m,$d,$y);
1356
1357Returns the day of the year (001 to 366)
1358
1359All arguments must be numeric.
1360
1361=item Date_NthDayOfYear
1362
1363 ($y,$m,$d,$h,$mn,$s) = Date_NthDayOfYear($y,$n);
1364
1365Returns the year, month, day, hour, minutes, and decimal seconds given
1366a floating point day of the year.
1367
1368All arguments must be numeric. $n must be greater than or equal to 1
1369and less than 366 on non-leap years and 367 on leap years.
1370
1371NOTE: When $n is a decimal number, the results are non-intuitive perhaps.
1372Day 1 is Jan 01 00:00. Day 2 is Jan 02 00:00. Intuitively, you
1373might think of day 1.5 as being 1.5 days after Jan 01 00:00, but this
1374would mean that Day 1.5 was Jan 02 12:00 (which is later than Day 2).
1375The best way to think of this function is a timeline starting at 1 and
1376ending at 366 (in a non-leap year). In terms of a delta, think of $n
1377as the number of days after Dec 31 00:00 of the previous year.
1378
1379=item Date_DaysInYear
1380
1381 $days = Date_DaysInYear($y);
1382
1383Returns the number of days in the year (365 or 366)
1384
1385=item Date_DaysInMonth
1386
1387 $days = Date_DaysInMonth($m,$y);
1388
1389Returns the number of days in the month.
1390
1391=item Date_WeekOfYear
1392
1393 $wkno = Date_WeekOfYear($m,$d,$y,$first);
1394
1395Figure out week number. $first is the first day of the week which is
1396usually 1 (Monday) or 7 (Sunday), but could be any number between 1 and 7
1397in practice.
1398
1399All arguments must be numeric.
1400
1401NOTE: This routine should only be called in rare cases. Use UnixDate with
1402the %W, %U, %J, %L formats instead. This routine returns a week between 0
1403and 53 which must then be "fixed" to get into the ISO-8601 weeks from 1 to
140453. A date which returns a week of 0 actually belongs to the last week of
1405the previous year. A date which returns a week of 53 may belong to the
1406first week of the next year.
1407
1408=item Date_LeapYear
1409
1410 $flag = Date_LeapYear($y);
1411
1412Returns 1 if the argument is a leap year
1413Written by David Muir Sharnoff <muir@idiom.com>
1414
1415=item Date_DaySuffix
1416
1417 $day = Date_DaySuffix($d);
1418
1419Add `st', `nd', `rd', `th' to a date (ie 1st, 22nd, 29th). Works for
1420international dates.
1421
1422=item Date_TimeZone
1423
1424 $tz = Date_TimeZone;
1425
1426This determines and returns the local timezone. If it is unable to determine
1427the local timezone, the following error occurs:
1428
1429 ERROR: Date::Manip unable to determine TimeZone.
1430
1431See The TIMEZONES section below for more information.
1432
1433=item Date_ConvTZ
1434
1435 $date = Date_ConvTZ($date);
1436 $date = Date_ConvTZ($date,$from);
1437 $date = Date_ConvTZ($date,"",$to);
1438 $date = Date_ConvTZ($date,$from,$to);
1439
1440This converts a date (which MUST be in the format returned by ParseDate)
1441from one timezone to another.
1442
1443If it is called with no arguments, the date is converted from the local
1444timezone to the timezone specified by the config variable ConvTZ (see
1445documentation on ConvTZ below). If ConvTZ is set to "IGNORE", no
1446conversion is done.
1447
1448If called with $from but no $to, the timezone is converted from the
1449timezone in $from to ConvTZ (of TZ if ConvTZ is not set). Again, no
1450conversion is done if ConvTZ is set to "IGNORE".
1451
1452If called with $to but no $from, $from defaults to ConvTZ (if set) or the
1453local timezone otherwise. Although this does not seem immediately obvious,
1454it actually makes sense. By default, all dates that are parsed are
1455converted to ConvTZ, so most of the dates being worked with will be stored
1456in that timezone.
1457
1458If Date_ConvTZ is called with both $from and $to, the date is converted
1459from the timezone $from to $to.
1460
1461NOTE: As in all other cases, the $date returned from Date_ConvTZ has no
1462timezone information included as part of it, so calling UnixDate with the
1463"%z" format will return the timezone that Date::Manip is working in
1464(usually the local timezone).
1465
1466Example: To convert 2/2/96 noon PST to CST (regardless of what timezone
1467you are in, do the following:
1468
1469 $date = ParseDate("2/2/96 noon");
1470 $date = Date_ConvTZ($date,"PST","CST");
1471
1472Both timezones MUST be in one of the formats listed below in the section
1473TIMEZONES.
1474
1475=item Date_Init
1476
1477 &Date_Init();
1478 &Date_Init("VAR=VAL","VAR=VAL",...);
1479 @list = Date_Init();
1480 @list = Date_Init("VAR=VAL","VAR=VAL",...);
1481
1482Normally, it is not necessary to explicitly call Date_Init. The first
1483time any of the other routines are called, Date_Init will be called to set
1484everything up. If for some reason you want to change the configuration of
1485Date::Manip, you can pass the appropriate string or strings into Date_Init
1486to reinitialize things.
1487
1488The strings to pass in are of the form "VAR=VAL". Any number may be
1489included and they can come in any order. VAR may be any configuration
1490variable. A list of all configuration variables is given in the section
1491CUSTOMIZING DATE::MANIP below. VAL is any allowed value for that variable.
1492For example, to switch from English to French and use non-US format (so
1493that 12/10 is Oct 12), do the following:
1494
1495 &Date_Init("Language=French","DateFormat=non-US");
1496
1497If Date_Init is called in list context, it will return a list of all
1498config variables and their values suitable for passing in to Date_Init
1499to return Date::Manip to the current state. The only possible problem is
1500that by default, holidays will not be erased, so you may need to prepend
1501the "EraseHolidays=1" element to the list.
1502
1503=item Date_IsWorkDay
1504
1505 $flag = Date_IsWorkDay($date [,$flag]);
1506
1507This returns 1 if $date is a work day. If $flag is non-zero, the time is
1508checked to see if it falls within work hours. It returns an empty string
1509if $date is not valid.
1510
1511=item Date_NextWorkDay
1512
1513 $date = Date_NextWorkDay($date,$off [,$time]);
1514
1515Finds the day $off work days from now. If $time is passed in, we must also
1516take into account the time of day.
1517
1518If $time is not passed in, day 0 is today (if today is a workday) or the
1519next work day if it isn't. In any case, the time of day is unaffected.
1520
1521If $time is passed in, day 0 is now (if now is part of a workday) or the
1522start of the very next work day.
1523
1524=item Date_PrevWorkDay
1525
1526 $date = Date_PrevWorkDay($date,$off [,$time]);
1527
1528Similar to Date_NextWorkDay.
1529
1530=item Date_NearestWorkDay
1531
1532 $date = Date_NearestWorkDay($date [,$tomorrowfirst]);
1533
1534This looks for the work day nearest to $date. If $date is a work day, it
1535is returned. Otherwise, it will look forward or backwards in time 1 day
1536at a time until a work day is found. If $tomorrowfirst is non-zero (or if
1537it is omitted and the config variable TomorrowFirst is non-zero), we look
1538to the future first. Otherwise, we look in the past first. In other words,
1539in a normal week, if $date is Wednesday, $date is returned. If $date is
1540Saturday, Friday is returned. If $date is Sunday, Monday is returned. If
1541Wednesday is a holiday, Thursday is returned if $tomorrowfirst is non-nil
1542or Tuesday otherwise.
1543
1544=item DateManipVersion
1545
1546 $version = DateManipVersion;
1547
1548Returns the version of Date::Manip.
1549
1550=back
1551
1552=head1 TIMEZONES
1553
1554The following timezone names are currently understood (and can be used in
1555parsing dates). These are zones defined in RFC 822.
1556
1557 Universal: GMT, UT
1558 US zones : EST, EDT, CST, CDT, MST, MDT, PST, PDT
1559 Military : A to Z (except J)
1560 Other : +HHMM or -HHMM
1561 ISO 8601 : +HH:MM, +HH, -HH:MM, -HH
1562
1563In addition, the following timezone abbreviations are also accepted. In a
1564few cases, the same abbreviation is used for two different timezones (for
1565example, NST stands for Newfoundland Standard -0330 and North Sumatra +0630).
1566In these cases, only 1 of the two is available. The one preceded by a "#"
1567sign is NOT available but is documented here for completeness. This list of
1568zones comes in part from the Time::Zone module by Graham Barr, David Muir
1569Sharnoff, and Paul Foley (with several additions by myself).
1570
1571 IDLW -1200 International Date Line West
1572 NT -1100 Nome
1573 HST -1000 Hawaii Standard
1574 CAT -1000 Central Alaska
1575 AHST -1000 Alaska-Hawaii Standard
1576 AKST -0900 Alaska Standard
1577 YST -0900 Yukon Standard
1578 HDT -0900 Hawaii Daylight
1579 AKDT -0800 Alaska Daylight
1580 YDT -0800 Yukon Daylight
1581 PST -0800 Pacific Standard
1582 PDT -0700 Pacific Daylight
1583 MST -0700 Mountain Standard
1584 MDT -0600 Mountain Daylight
1585 CST -0600 Central Standard
1586 CDT -0500 Central Daylight
1587 EST -0500 Eastern Standard
1588 ACT -0500 Brazil, Acre
1589 SAT -0400 Chile
1590 BOT -0400 Bolivia
1591 EDT -0400 Eastern Daylight
1592 AST -0400 Atlantic Standard
1593 AMT -0400 Brazil, Amazon
1594 ACST -0400 Brazil, Acre Daylight
1595 #NST -0330 Newfoundland Standard nst=North Sumatra +0630
1596 NFT -0330 Newfoundland
1597 #GST -0300 Greenland Standard gst=Guam Standard +1000
1598 #BST -0300 Brazil Standard bst=British Summer +0100
1599 BRST -0300 Brazil Standard
1600 BRT -0300 Brazil Standard
1601 AMST -0300 Brazil, Amazon Daylight
1602 ADT -0300 Atlantic Daylight
1603 ART -0300 Argentina
1604 NDT -0230 Newfoundland Daylight
1605 AT -0200 Azores
1606 BRST -0200 Brazil Daylight (official time)
1607 FNT -0200 Brazil, Fernando de Noronha
1608 WAT -0100 West Africa
1609 FNST -0100 Brazil, Fernando de Noronha Daylight
1610 GMT +0000 Greenwich Mean
1611 UT +0000 Universal (Coordinated)
1612 UTC +0000 Universal (Coordinated)
1613 WET +0000 Western European
1614 CET +0100 Central European
1615 FWT +0100 French Winter
1616 MET +0100 Middle European
1617 MEZ +0100 Middle European
1618 MEWT +0100 Middle European Winter
1619 SWT +0100 Swedish Winter
1620 BST +0100 British Summer bst=Brazil standard -0300
1621 GB +0100 GMT with daylight savings
1622 WEST +0000 Western European Daylight
1623 CEST +0200 Central European Summer
1624 EET +0200 Eastern Europe, USSR Zone 1
1625 FST +0200 French Summer
1626 MEST +0200 Middle European Summer
1627 MESZ +0200 Middle European Summer
1628 METDST +0200 An alias for MEST used by HP-UX
1629 SAST +0200 South African Standard
1630 SST +0200 Swedish Summer sst=South Sumatra +0700
1631 EEST +0300 Eastern Europe Summer
1632 BT +0300 Baghdad, USSR Zone 2
1633 MSK +0300 Moscow
1634 EAT +0300 East Africa
1635 IT +0330 Iran
1636 ZP4 +0400 USSR Zone 3
1637 MSD +0300 Moscow Daylight
1638 ZP5 +0500 USSR Zone 4
1639 IST +0530 Indian Standard
1640 ZP6 +0600 USSR Zone 5
1641 NOVST +0600 Novosibirsk time zone, Russia
1642 NST +0630 North Sumatra nst=Newfoundland Std -0330
1643 #SST +0700 South Sumatra, USSR Zone 6 sst=Swedish Summer +0200
1644 JAVT +0700 Java
1645 CCT +0800 China Coast, USSR Zone 7
1646 AWST +0800 Australian Western Standard
1647 WST +0800 West Australian Standard
1648 PHT +0800 Asia Manila
1649 JST +0900 Japan Standard, USSR Zone 8
1650 ROK +0900 Republic of Korea
1651 ACST +0930 Australian Central Standard
1652 CAST +0930 Central Australian Standard
1653 AEST +1000 Australian Eastern Standard
1654 EAST +1000 Eastern Australian Standard
1655 GST +1000 Guam Standard, USSR Zone 9 gst=Greenland Std -0300
1656 ACDT +1030 Australian Central Daylight
1657 CADT +1030 Central Australian Daylight
1658 AEDT +1100 Australian Eastern Daylight
1659 EADT +1100 Eastern Australian Daylight
1660 IDLE +1200 International Date Line East
1661 NZST +1200 New Zealand Standard
1662 NZT +1200 New Zealand
1663 NZDT +1300 New Zealand Daylight
1664
1665Others can be added in the future upon request.
1666
1667Date::Manip must be able to determine the timezone the user is in. It does
1668this by looking in the following places:
1669
1670 $Date::Manip::TZ (set with Date_Init or in Manip.pm)
1671 $ENV{TZ}
1672 the unix `date` command (if available)
1673 $main::TZ
1674 /etc/TIMEZONE
1675 /etc/timezone
1676
1677At least one of these should contain a timezone in one of the supported
1678forms. If none do by default, the TZ variable must be set with Date_Init.
1679
1680The timezone may be in the STD#DST format (in which case both abbreviations
1681must be in the table above) or any of the formats described above. The
1682STD#DST format is NOT available when parsing a date however. The following
1683forms are also available and are treated similar to the STD#DST forms:
1684
1685 US/Pacific
1686 US/Mountain
1687 US/Central
1688 US/Eastern
1689 Canada/Pacific
1690 Canada/Mountain
1691 Canada/Central
1692 Canada/Eastern
1693
1694=head1 BUSINESS MODE
1695
1696Anyone using business mode is going to notice a few quirks about it which
1697should be explained. When I designed business mode, I had in mind what UPS
1698tells me when they say 2 day delivery, or what the local business which
1699promises 1 business day turnaround really means.
1700
1701If you do a business day calculation (with the workday set to 9:00-5:00),
1702you will get the following:
1703
1704 Saturday at noon + 1 business day = Tuesday at 9:00
1705 Saturday at noon - 1 business day = Friday at 9:00
1706
1707What does this mean?
1708
1709We have a business that works 9-5 and they have a drop box so I can drop
1710things off over the weekend and they promise 1 business day turnaround. If
1711I drop something off Friday night, Saturday, or Sunday, it doesn't matter.
1712They're going to get started on it Monday morning. It'll be 1 business day
1713to finish the job, so the earliest I can expect it to be done is around
171417:00 Monday or 9:00 Tuesday morning. Unfortunately, there is some
1715ambiguity as to what day 17:00 really falls on, similar to the ambiguity
1716that occurs when you ask what day midnight falls on. Although it's not the
1717only answer, Date::Manip treats midnight as the beginning of a day rather
1718than the end of one. In the same way, 17:00 is equivalent to 9:00 the next
1719day and any time the date calculations encounter 17:00, it automatically
1720switch to 9:00 the next day. Although this introduces some quirks, I think
1721this is justified. You just have to treat 17:00/9:00 as being ambiguous
1722(in the same way you treat midnight as being ambiguous).
1723
1724Equivalently, if I want a job to be finished on Saturday (despite the fact
1725that I cannot pick it up since the business is closed), I have to drop it
1726off no later than Friday at 9:00. That gives them a full business day to
1727finish it off. Of course, I could just as easily drop it off at 17:00
1728Thursday, or any time between then and 9:00 Friday. Again, it's a matter
1729of treating 9:00 as ambiguous.
1730
1731So, in case the business date calculations ever produce results that you
1732find confusing, I believe the solution is to write a wrapper which,
1733whenever it sees a date with the time of exactly 9:00, it treats it
1734specially (depending on what you want.
1735
1736So Saturday + 1 business day = Tuesday at 9:00 (which means anything
1737from Monday 17:00 to Tuesday 9:00), but Monday at 9:01 + 1 business
1738day = Tuesday at 9:01 which is exact.
1739
1740If this is not exactly what you have in mind, don't use the DateCalc
1741routine. You can probably get whatever behavior you want using the
1742routines Date_IsWorkDay, Date_NextWorkDay, and Date_PrevWorkDay described
1743above.
1744
1745=head1 CUSTOMIZING DATE::MANIP
1746
1747There are a number of variables which can be used to customize the way
1748Date::Manip behaves. There are also several ways to set these variables.
1749
1750At the top of the Manip.pm file, there is a section which contains all
1751customization variables. These provide the default values.
1752
1753These can be overridden in a global config file if one is present (this
1754file is optional). If the GlobalCnf variable is set in the Manip.pm file,
1755it contains the full path to a config file. If the file exists, it's
1756values will override those set in the Manip.pm file. A sample config file
1757is included with the Date::Manip distribution. Modify it as appropriate
1758and copy it to some appropriate directory and set the GlobalCnf variable in
1759the Manip.pm file.
1760
1761Each user can have a personal config file which is of the same form as the
1762global config file. The variables PersonalCnf and PersonalCnfPath set the
1763name and search path for the personal config file. This file is also
1764optional. If present, it overrides any values set in the global file.
1765
1766NOTE: if you use business mode calculations, you must have a config file
1767(either global or personal) since this is the only place where you can
1768define holidays.
1769
1770Finally, any variables passed in through Date_Init override all other
1771values.
1772
1773A config file can be composed of several sections. The first section sets
1774configuration variables. Lines in this section are of the form:
1775
1776 VARIABLE = VALUE
1777
1778For example, to make the default language French, include the line:
1779
1780 Language = French
1781
1782Only variables described below may be used. Blank lines and lines beginning
1783with a pound sign (#) are ignored. All spaces are optional and strings are
1784case insensitive.
1785
1786A line which starts with an asterisk (*) designates a new section. For
1787example, the HOLIDAY section starts with a line:
1788
1789 *Holiday
1790
1791The various sections are defined below.
1792
1793=head1 DATE::MANIP VARIABLES
1794
1795All Date::Manip variables which can be used are described in the following
1796section.
1797
1798=over 4
1799
1800=item IgnoreGlobalCnf
1801
1802If this variable is used (any value is ignored), the global config file
1803is not read. It must be present in the initial call to Date_Init or the
1804global config file will be read.
1805
1806=item EraseHolidays
1807
1808If this variable is used (any value is ignored), the current list of
1809defined holidays is erased. A new set will be set the next time a
1810config file is read in. This can be set in either the global config file
1811or as a Date_Init argument (in which case holidays can be read in from
1812both the global and personal config files) or in the personal config file
1813(in which case, only holidays in the personal config file are counted).
1814
1815=item PathSep
1816
1817This is a regular expression used to separate multiple paths. For example,
1818on Unix, it defaults to a colon (:) so that multiple paths can be written
1819PATH1:PATH2 . For Win32 platforms, it defaults to a semicolon (;) so that
1820paths such as "c:\;d:\" will work.
1821
1822=item GlobalCnf
1823
1824This variable can be passed into Date_Init to point to a global
1825configuration file. The value must be the complete path to a config file.
1826
1827By default, no global config file is read. Any time a global config file
1828is read, the holidays are erased.
1829
1830Paths may have a tilde (~) expansion on platforms where this is supported
1831(currently Unix and VMS).
1832
1833=item PersonalCnf
1834
1835This variable can be passed into Date_Init or set in a global config file
1836to set the name of the personal configuration file.
1837
1838The default name for the config file is .DateManip.cnf on all Unix
1839platforms and Manip.cnf on all non-Unix platforms (because some of them
1840insist on 8.3 character filenames :-).
1841
1842=item PersonalCnfPath
1843
1844This is a list of paths separated by the separator specified by the PathSep
1845variable. These paths are each checked for the PersonalCnf config file.
1846
1847Paths may have a tilde (~) expansion on platforms where this is supported
1848(currently Unix and VMS).
1849
1850=item Language
1851
1852Date::Manip can be used to parse dates in many different languages.
1853Currently, it is configured to read the following languages (the version
1854in which they added is included for historical interest):
1855
1856 English (default)
1857 French (5.02)
1858 Swedish (5.05)
1859 German (5.31)
1860 Dutch (5.32) aka Nederlands
1861 Polish (5.32)
1862 Spanish (5.33)
1863 Portuguese (5.34)
1864 Romanian (5.35)
1865 Italian (5.35)
1866 Russian (5.41)
1867 Turkish (5.41)
1868 Danish (5.41)
1869
1870Others can be added easily. Language is set to the language used to parse
1871dates. If you are interested in providing a translation for a new
1872language, email me (see the AUTHOR section below) and I'll send you a list
1873of things that I need.
1874
1875=item DateFormat
1876
1877Different countries look at the date 12/10 as Dec 10 or Oct 12. In the
1878United States, the first is most common, but this certainly doesn't hold
1879true for other countries. Setting DateFormat to "US" forces the first
1880behavior (Dec 10). Setting DateFormat to anything else forces the second
1881behavior (Oct 12).
1882
1883=item TZ
1884
1885If set, this defines the local timezone. See the TIMEZONES section above
1886for information on it's format.
1887
1888=item ConvTZ
1889
1890All date comparisons and calculations must be done in a single time zone in
1891order for them to work correctly. So, when a date is parsed, it should be
1892converted to a specific timezone. This allows dates to easily be compared
1893and manipulated as if they are all in a single timezone.
1894
1895The ConvTZ variable determines which timezone should be used to store dates
1896in. If it is left blank, all dates are converted to the local timezone
1897(see the TZ variable above). If it is set to one of the timezones listed
1898above, all dates are converted to this timezone. Finally, if it is set to
1899the string "IGNORE", all timezone information is ignored as the dates are
1900read in (in this case, the two dates "1/1/96 12:00 GMT" and "1/1/96 12:00
1901EST" would be treated as identical).
1902
1903=item Internal
1904
1905When a date is parsed using ParseDate, that date is stored in an internal
1906format which is understood by the Date::Manip routines UnixDate and
1907DateCalc. Originally, the format used to store the date internally was:
1908
1909 YYYYMMDDHH:MN:SS
1910
1911It has been suggested that I remove the colons (:) to shorten this to:
1912
1913 YYYYMMDDHHMNSS
1914
1915The main advantage of this is that some databases are colon delimited which
1916makes storing a date from Date::Manip tedious.
1917
1918In order to maintain backwards compatibility, the Internal variable was
1919introduced. Set it to 0 (to use the old format) or 1 (to use the new
1920format).
1921
1922=item FirstDay
1923
1924It is sometimes necessary to know what day of week is regarded as first.
1925By default, this is set to Monday, but many countries and people will
1926prefer Sunday (and in a few cases, a different day may be desired). Set
1927the FirstDay variable to be the first day of the week (1=Monday, 7=Sunday)
1928Monday should be chosen to to comply with ISO 8601.
1929
1930=item WorkWeekBeg, WorkWeekEnd
1931
1932The first and last days of the work week. By default, Monday and Friday.
1933WorkWeekBeg must come before WorkWeekEnd numerically. The days are
1934numbered from 1 (Monday) to 7 (Sunday).
1935
1936There is no way to handle an odd work week of Thu to Mon for example or 10
1937days on, 4 days off.
1938
1939=item WorkDay24Hr
1940
1941If this is non-nil, a work day is treated as being 24 hours long. The
1942WorkDayBeg and WorkDayEnd variables are ignored in this case.
1943
1944=item WorkDayBeg, WorkDayEnd
1945
1946The times when the work day starts and ends. WorkDayBeg must come before
1947WorkDayEnd (i.e. there is no way to handle the night shift where the work
1948day starts one day and ends another). Also, the workday MUST be more than
1949one hour long (of course, if this isn't the case, let me know... I want a
1950job there!).
1951
1952The time in both can be in any valid time format (including international
1953formats), but seconds will be ignored.
1954
1955=item TomorrowFirst
1956
1957Periodically, if a day is not a business day, we need to find the nearest
1958business day to it. By default, we'll look to "tomorrow" first, but if this
1959variable is set to 0, we'll look to "yesterday" first. This is only used in
1960the Date_NearestWorkDay and is easily overridden (see documentation for that
1961function).
1962
1963=item DeltaSigns
1964
1965Prior to Date::Manip version 5.07, a negative delta would put negative
1966signs in front of every component (i.e. "0:0:-1:-3:0:-4"). By default,
19675.07 changes this behavior to print only 1 or two signs in front of the
1968year and day elements (even if these elements might be zero) and the sign
1969for year/month and day/hour/minute/second are the same. Setting this
1970variable to non-zero forces deltas to be stored with a sign in front of
1971every element (including elements equal to 0).
1972
1973=item Jan1Week1
1974
1975ISO 8601 states that the first week of the year is the one which contains
1976Jan 4 (i.e. it is the first week in which most of the days in that week
1977fall in that year). This means that the first 3 days of the year may
1978be treated as belonging to the last week of the previous year. If this
1979is set to non-nil, the ISO 8601 standard will be ignored and the first
1980week of the year contains Jan 1.
1981
1982=item YYtoYYYY
1983
1984By default, a 2 digit year is treated as falling in the 100 year period of
1985CURR-89 to CURR+10. YYtoYYYY may be set to any integer N to force a 2
1986digit year into the period CURR-N to CURR+(99-N). A value of 0 forces
1987the year to be the current year or later. A value of 99 forces the year
1988to be the current year or earlier. Since I do no checking on the value of
1989YYtoYYYY, you can actually have it any positive or negative value to force
1990it into any century you want.
1991
1992YYtoYYYY can also be set to "C" to force it into the current century, or
1993to "C##" to force it into a specific century. So, no (1998), "C" forces
19942 digit years to be 1900-1999 and "C18" would force it to be 1800-1899.
1995
1996It can also be set to the form "C####" to force it into a specific 100
1997year period. C1950 refers to 1950-2049.
1998
1999=item UpdateCurrTZ
2000
2001If a script is running over a long period of time, the timezone may change
2002during the course of running it (i.e. when daylight savings time starts or
2003ends). As a result, parsing dates may start putting them in the wrong time
2004zone. Since a lot of overhead can be saved if we don't have to check the
2005current timezone every time a date is parsed, by default checking is turned
2006off. Setting this to non-nil will force timezone checking to be done every
2007time a date is parsed... but this will result in a considerable performance
2008penalty.
2009
2010A better solution would be to restart the process on the two days per year
2011where the timezone switch occurs.
2012
2013=item IntCharSet
2014
2015If set to 0, use the US character set (7-bit ASCII) to return strings such
2016as the month name. If set to 1, use the appropriate international character
2017set. For example, If you want your French representation of Decemeber to
2018have the accent over the first "e", you'll want to set this to 1.
2019
2020=item ForceDate
2021
2022This variable can be set to a date in the format: YYYY-MM-DD-HH:MN:SS
2023to force the current date to be interpreted as this date. Since the current
2024date is used in parsing, this string will not be parsed and MUST be in the
2025format given above.
2026
2027=back
2028
2029=head1 HOLIDAY SECTION
2030
2031The holiday section of the config file is used to define holidays. Each
2032line is of the form:
2033
2034 DATE = HOLIDAY
2035
2036HOLIDAY is the name of the holiday (or it can be blank in which case the
2037day will still be treated as a holiday... for example the day after
2038Thanksgiving or Christmas is often a work holiday though neither are
2039named).
2040
2041DATE is a string which can be parsed to give a valid date in any year. It
2042can be of the form
2043
2044 Date
2045 Date + Delta
2046 Date - Delta
2047 Recur
2048
2049A valid holiday section would be:
2050
2051 *Holiday
2052
2053 1/1 = New Year's Day
2054 third Monday in Feb = Presidents' Day
2055 fourth Thu in Nov = Thanksgiving
2056
2057 # The Friday after Thanksgiving is an unnamed holiday most places
2058 fourth Thu in Nov + 1 day =
2059
2060 1*0:0:0:0:0:0*EASTER = Easter
2061 1*11:0:11:0:0:0*CWD = Veteran's Day (observed)
2062 1*0:0:0:0:0:0*EASTER,PD5 = Good Friday
2063
2064In a Date + Delta or Date - Delta string, you can use business mode by
2065including the appropriate string (see documentation on DateCalc) in the
2066Date or Delta. So (in English), the first workday before Christmas could
2067be defined as:
2068
2069 12/25 - 1 business day =
2070
2071The date's may optionally contain the year. For example, the dates
2072
2073 1/1
2074 1/1/1999
2075
2076refers to Jan 1 in any year or in only 1999 respectively. For dates that
2077refer to any year, the date must be written such that by simply appending
2078the year (separated by spaces) it can be correctly interpreted. This
2079will work for everything except ISO 8601 dates, so ISO 8601 dates may
2080not be used in this case.
2081
2082In cases where you are interested in business type calculations, you'll
2083want to define most holidays using recurrences, since they can define
2084when a holiday is celebrated in the financial world. For example,
2085Christmas chould be defined as:
2086
2087 1*12:0:24:0:0:0*FW1 = Christmas
2088
2089NOTE: It was pointed out to me that using a similar type recurrence to
2090define New Years does not work. The recurrence:
2091
2092 1*12:0:31:0:0:0*FW1
2093
2094fails (worse, it goes into an infinite loop). The problem is that each
2095holiday definition is applied to a specific year and it expects to find
2096the holiday for that year. When this recurrence is applied to the year
20971995, it returns the holiday for 1996 and fails.
2098
2099Use the recurrence:
2100
2101 1*1:0:1:0:0:0*NWD
2102
2103instead.
2104
2105If you wanted to define both Christmas and Boxing days (Boxing is the
2106day after Christmas, and is celebrated in some parts of the world), you
2107could do it in one of the following ways:
2108
2109 1*12:0:24:0:0:0*FW1 = Christmas
2110 1*12:0:25:0:0:0*FW1 = Boxing
2111
2112 1*12:0:24:0:0:0*FW1 = Christmas
2113 01*12:0:24:0:0:0*FW1 = Boxing
2114
2115 1*12:0:24:0:0:0*FW1 = Christmas
2116 1*12:0:25:0:0:0*FW1,a = Boxing
2117
2118The following examples will NOT work:
2119
2120 1*12:0:24:0:0:0*FW1 = Christmas
2121 1*12:0:24:0:0:0*FW2 = Boxing
2122
2123 1*12:0:24:0:0:0*FW1 = Christmas
2124 1*12:0:24:0:0:0*FW1 = Boxing
2125
2126The reasoning behind all this is as follows:
2127
2128Holidays go into affect the minute they are parsed. So, in the case of:
2129
2130 1*12:0:24:0:0:0*FW1 = Christmas
2131 1*12:0:24:0:0:0*FW2 = Boxing
2132
2133the minute the first line is parsed, Christmas is defined as a holiday.
2134The second line then steps forward 2 work days (skipping Christmas since
2135that's no longer a work day) and define the work day two days after
2136Christmas, NOT the day after Christmas.
2137
2138An good alternative would appear to be:
2139
2140 1*12:0:24:0:0:0*FW1 = Christmas
2141 1*12:0:24:0:0:0*FW1 = Boxing
2142
2143This unfortunately fails because the recurrences are currently stored in a
2144hash. Since these two recurrences are identical, they fail (the first one
2145is overwritten by the second and in essense, Christmas is never defined).
2146
2147To fix this, make them unique with either a fake flag (which is ignored):
2148
2149 1*12:0:24:0:0:0*FW1,a = Boxing
2150
2151or adding an innocuous 0 somewhere:
2152
2153 01*12:0:24:0:0:0*FW1 = Boxing
2154
2155The other good alternative would be to make two completely different
2156recurrences such as:
2157
2158 1*12:0:24:0:0:0*FW1 = Christmas
2159 1*12:0:25:0:0:0*FW1 = Boxing
2160
2161At times, you may want to switch back and forth between two holiday files.
2162This can be done by calling the following:
2163
2164 &Date_Init("EraseHolidays=1","PersonalCnf=FILE1");
2165 ...
2166 &Date_Init("EraseHolidays=1","PersonalCnf=FILE2");
2167 ...
2168
2169=head1 EVENTS SECTION
2170
2171The Events section of the config file is similar to the Holiday section.
2172It is used to name certain days or times, but there are a few important
2173differences:
2174
2175=over 4
2176
2177=item Events can be assigned to any time and duration
2178
2179All holidays are exactly 1 day long. They are assigned to a period
2180of time from midnight to midnight.
2181
2182Events can be based at any time of the day, and may be of any duration.
2183
2184=item Events don't affect business mode calculations
2185
2186Unlike holidays, events are completely ignored when doing business
2187mode calculations.
2188
2189=back
2190
2191Whereas holidays were added with business mode math in mind, events
2192were added with calendar and scheduling applications in mind.
2193
2194Every line in the events section is of the form:
2195
2196 EVENT = NAME
2197
2198where NAME is the name of the event, and EVENT defines when it occurs
2199and it's duration. An EVENT can be defined in the following ways:
2200
2201 Date
2202 Date*
2203 Recur [NYI]
2204 Recur* [NYI]
2205
2206 Date ; Date
2207 Date ; Delta
2208 Recur ; Delta [NYI]
2209
2210 Date ; Delta ; Delta [NYI]
2211 Recur ; Delta ; Delta [NYI]
2212
2213Here, Date* refers to a string containing a Date with NO TIME fields
2214(Jan 12, 1/1/2000, 2010-01-01) while Date does contain time fields.
2215Similarily, Recur* stands for a recurrence with the time fields all
2216equal to 0) while Recur stands for a recurrence with at least one
2217non-zero time field.
2218
2219Both Date* and Recur* refer to an event very similar to a holiday which
2220goes from midnight to midnight.
2221
2222Date and Recur refer to events which occur at the time given and with
2223a duration of 1 hour.
2224
2225Events given by "Date ; Date", "Date ; Delta", and "Recur ; Delta"
2226contain both the starting date and either ending date or duration.
2227
2228Events given as three elements "Date ; Delta ; Delta" or "Recur ; Delta ;
2229Delta" take a date and add both deltas to it to give the starting and
2230ending time of the event. The order and sign of the deltas is
2231unimportant (and both can be the same sign to give a range of times
2232which does not contain the base date).
2233
2234Items marked with [NYI] are not yet implemented but will be by the
2235time this is released.
2236
2237=head1 BACKWARDS INCOMPATIBILITIES
2238
2239For the most part, Date::Manip has remained backward compatible at every
2240release. There have been a few minor incompatibilities introduced at
2241various stages. Major differences are marked with bullets.
2242
2243=over 4
2244
2245=item VERSION 5.41
2246
2247=item Changed path separator for VMS
2248
2249Since ":" is used in some VMS paths, it should not have been used as
2250the path separator. It has been changed to a newline ("\n") character.
2251
2252=item Delta_Format behavior changed
2253
2254The entire delta is exact if no month component is present (previously,
2255no year or month component could be present).
2256
2257=item VERSION 5.38
2258
2259=item Removed Date_DaysSince999
2260
2261The Date_DaysSince999 function (deprecated in 5.35) has been removed.
2262
2263=item VERSION 5.35
2264
2265=over 4
2266
2267=item Deprected Date_DaysSince999
2268
2269In fixing support for the years 0000-0999, I rewrote Date_DaysSince999 to
2270be Date_DaysSince1BC. The Date_DaysSince999 function will be removed.
2271
2272=item * Added PathSep variable
2273
2274In order to better support Win32 platforms, I added the PathSep config
2275variable. This will allow the use of paths such as "c:\date" on Win32
2276platforms. Old config files on Win32 platforms (which were not working
2277correctly in many cases) may not work if they contain path information to
2278the personal config file.
2279
2280=back
2281
2282=item VERSION 5.34
2283
2284=over 4
2285
2286=item * All Date::Manip variables are no longer accessible
2287
2288Previously, Date::Manip variables were declared using a full package name.
2289Now, they are declared with the my() function. This means that internal
2290variables are no longer accessible outside of the module.
2291
2292=item Week interpretation in business mode deltas
2293
2294A business mode delta containing a week value used to be treated as 7 days.
2295A much more likely interpretation of a week is Monday to Monday, regardless
2296of holidays, so this is now the behavior.
2297
2298=item %z UnixDate format
2299
2300The %z UnixDate format used to return the Timezone abbreviation. It now
2301returns it as a GMT offset (i.e. -0500). %Z still returns the Timezone
2302abbreviation.
2303
2304=item Formats "22nd sunday" returns the intuitive value
2305
2306The date "22nd sunday" used to return the Sunday of the 22nd week of the
2307year (which could be the 21st, 22nd, or 23rd Sunday of the year depending
2308on how weeks were defined). Now, it returns the 22nd Sunday of the year
2309regardless.
2310
2311=item Separator in DD/YYmmm and mmmDD/YY formats no longer optional
2312
2313Previously, the date "Dec1065" would return Dec 10, 1965. After adding
2314the YYYYmmm and mmmYYYY formats, this was no longer possible. The separator
2315between DD and YY is no longer optional, so
2316
2317 Dec1065 returns December 1, 1065
2318 Dec10/65 returns December 10, 1965
2319
2320=item * Date_Cmp added
2321
2322This is not a backwards incompatibility... but is added to help prepare for
2323a future incompatibility. In one of the next versions of Date::Manip, the
2324internal format of the date will change to include timezone information.
2325All date comparisons should be made using Date_Cmp (which currently does
2326nothing more than call the perl "cmp" command, but which will important
2327when comparing dates that include the timezone).
2328
2329=back
2330
2331=item VERSION 5.32
2332
2333=over 4
2334
2335=item Date_Init arguments
2336
2337The old style Date_Init arguments that were deprecated in version 5.07
2338have been removed.
2339
2340=item * DateManip.cnf change
2341
2342Changed .DateManip.cnf to Manip.cnf (to get rid of problems on OS's
2343that insist on 8.3 filenames) for all non-Unix platforms (Wintel, VMS,
2344Mac). For all Unix platforms, it's still .DateManip.cnf . It will only
2345look in the user's home directory on VMS and Unix.
2346
2347=back
2348
2349=item VERSION 5.30
2350
2351=over 4
2352
2353=item * Delta format changed
2354
2355A week field has been added to the internal format of the delta. It now
2356reads "Y:M:W:D:H:MN:S" instead of "Y:M:D:H:MN:S".
2357
2358=back
2359
2360=item VERSION 5.21
2361
2362=over 4
2363
2364=item Long running processes may give incorrect timezone
2365
2366A process that runs during a timezone change (Daylight Saving Time
2367specifically) may report the wrong timezone. See the UpdateCurrTZ variable
2368for more information.
2369
2370=item UnixDate "%J", "%W", and "%U" formats fixed
2371
2372The %J, %W, and %U will no longer report a week 0 or a week 53 if it should
2373really be week 1 of the following year. They now report the correct week
2374number according to ISO 8601.
2375
2376=back
2377
2378=item VERSION 5.20
2379
2380=over 4
2381
2382=item * ParseDate formats removed (ISO 8601 compatibility)
2383
2384Full support for ISO 8601 formats was added. As a result, some formats
2385which previously worked may no longer be parsed since they conflict with an
2386ISO 8601 format. These include MM-DD-YY (conflicts with YY-MM-DD) and
2387YYMMDD (conflicts with YYYYMM). MM/DD/YY still works, so the first form
2388can be kept easily by changing "-" to "/". YYMMDD can be changed to
2389YY-MM-DD before being parsed. Whenever parsing dates using dashes as
2390separators, they will be treated as ISO 8601 dates. You can get around
2391this by converting all dashes to slashes.
2392
2393=item * Week day numbering
2394
2395The day numbering was changed from 0-6 (sun-sat) to 1-7 (mon-sun) to be
2396ISO 8601 compatible. Weeks start on Monday (though this can be overridden
2397using the FirstDay config variable) and the 1st week of the year contains
2398Jan 4 (though it can be forced to contain Jan 1 with the Jan1Week1 config
2399variable).
2400
2401=back
2402
2403=item VERSION 5.07
2404
2405=over 4
2406
2407=item UnixDate "%s" format
2408
2409Used to return the number of seconds since 1/1/1970 in the current
2410timezone. It now returns the number of seconds since 1/1/1970 GMT.
2411The "%o" format was added which returns what "%s" previously did.
2412
2413=item Internal format of delta
2414
2415The format for the deltas returned by ParseDateDelta changed. Previously,
2416each element of a delta had a sign attached to it (+1:+2:+3:+4:+5:+6). The
2417new format removes all unnecessary signs by default (+1:2:3:4:5:6). Also,
2418because of the way deltas are normalized (see documentation on
2419ParseDateDelta), at most two signs are included. For backwards
2420compatibility, the config variable DeltaSigns was added. If set to 1, all
2421deltas include all 6 signs.
2422
2423=item Date_Init arguments
2424
2425The format of the Date_Init calling arguments changed. The
2426old method
2427
2428 &Date_Init($language,$format,$tz,$convtz);
2429
2430is still supported , but this support will likely disappear in the future.
2431Use the new calling format instead:
2432
2433 &Date_Init("var=val","var=val",...);
2434
2435NOTE: The old format is no longer supported as of version 5.32 .
2436
2437=back
2438
2439=back
2440
2441=head1 KNOWN PROBLEMS
2442
2443The following are not bugs in Date::Manip, but they may give some people
2444problems.
2445
2446=over 4
2447
2448=item Unable to determine TimeZone
2449
2450Perhaps the most common problem occurs when you get the error:
2451
2452 Error: Date::Manip unable to determine TimeZone.
2453
2454Date::Manip tries hard to determine the local timezone, but on some
2455machines, it cannot do this (especially non-unix systems). To fix this,
2456just set the TZ variable, either at the top of the Manip.pm file,, in the
2457DateManip.cnf file, or in a call to Date_Init. I suggest using the form
2458"EST5EDT" so you don't have to change it every 6 months when going to or
2459from daylight savings time.
2460
2461Windows NT does not seem to set the TimeZone by default. From the
2462Perl-Win32-Users mailing list:
2463
2464 > How do I get the TimeZone on my NT?
2465 >
2466 > $time_zone = $ENV{'TZ'};
2467 >
2468 You have to set the variable before, WinNT doesn't set it by
2469 default. Open the properties of "My Computer" and set a SYSTEM
2470 variable TZ to your timezone. Jenda@Krynicky.cz
2471
2472This might help out some NT users.
2473
2474A minor (false) assumption that some users might make is that since
2475Date::Manip passed all of it's tests at install time, this should not occur
2476and are surprised when it does.
2477
2478Some of the tests are timezone dependent. Since the tests all include
2479input and expected output, I needed to know in advance what timezone they
2480would be run in. So, the tests all explicitly set the timezone using the
2481TZ configuration variable passed into Date_Init. Since this overrides any
2482other method of determining the timezone, Date::Manip uses this and doesn't
2483have to look elsewhere for the timezone.
2484
2485When running outside the tests, Date::Manip has to rely on it's other
2486methods for determining the timezone.
2487
2488=item Complaining about getpwnam/getpwuid
2489
2490Another problem is when running on Micro$oft OS'es. I have added many
2491tests to catch them, but they still slip through occasionally. If any ever
2492complain about getpwnam/getpwuid, simply add one of the lines:
2493
2494 $ENV{OS} = Windows_NT
2495 $ENV{OS} = Windows_95
2496
2497to your script before
2498
2499 use Date::Manip
2500
2501=item Date::Manip is slow
2502
2503The reasons for this are covered in the SHOULD I USE DATE::MANIP section
2504above.
2505
2506Some things that will definitely help:
2507
2508Version 5.21 does run noticeably faster than earlier versions due to
2509rethinking some of the initialization, so at the very least, make sure you
2510are running this version or later.
2511
2512ISO-8601 dates are parsed first and fastest. Use them whenever possible.
2513
2514Avoid parsing dates that are referenced against the current time (in 2
2515days, today at noon, etc.). These take a lot longer to parse.
2516
2517 Example: parsing 1065 dates with version 5.11 took 48.6 seconds, 36.2
2518 seconds with version 5.21, and parsing 1065 ISO-8601 dates with version
2519 5.21 took 29.1 seconds (these were run on a slow, overloaded computer with
2520 little memory... but the ratios should be reliable on a faster computer).
2521
2522Business date calculations are extremely slow. You should consider
2523alternatives if possible (i.e. doing the calculation in exact mode and then
2524multiplying by 5/7). There will be an approximate business mode in one of
2525the next versions which will be much faster (though less accurate) which
2526will do something like this. Whenever possible, use this mode. And who
2527needs a business date more accurate than "6 to 8 weeks" anyway huh :-)
2528
2529Never call Date_Init more than once. Unless you're doing something very
2530strange, there should never be a reason to anyway.
2531
2532=item Sorting Problems
2533
2534If you use Date::Manip to sort a number of dates, you must call Date_Init
2535either explicitly, or by way of some other Date::Manip routine before it
2536is used in the sort. For example, the following code fails:
2537
2538 use Date::Manip;
2539 # &Date_Init;
2540 sub sortDate {
2541 my($date1, $date2);
2542 $date1 = &ParseDate($a);
2543 $date2 = &ParseDate($b);
2544 return (&Date_Cmp($date1,$date2));
2545 }
2546 @dates = ("Fri 16 Aug 96",
2547 "Mon 19 Aug 96",
2548 "Thu 15 Aug 96");
2549 @i=sort sortDate @dates;
2550
2551but if you uncomment the Date_Init line, it works. The reason for this is
2552that the first time you call Date_Init, it initializes a number of items
2553used by Date::Manip. Some of these have to be sorted (regular expressions
2554sorted by length to ensure the longest match). It turns out that perl
2555has a bug in it which does not allow a sort within a sort. At some point,
2556this should be fixed, but for now, the best thing to do is to call Date_Init
2557explicitly. The bug exists in all versions up to 5.005 (I haven't
2558tested 5.6.0 yet).
2559
2560NOTE: This is an EXTREMELY inefficient way to sort data. Instead, you
2561should parse the dates with ParseDate, sort them using a normal string
2562comparison, and then convert them back to the format desired using
2563UnixDate.
2564
2565=item RCS Control
2566
2567If you try to put Date::Manip under RCS control, you are going to have
2568problems. Apparently, RCS replaces strings of the form "$Date...$" with
2569the current date. This form occurs all over in Date::Manip. To prevent the
2570RCS keyword expansion, checkout files using "co -ko". Since very few people
2571will ever have a desire to do this (and I don't use RCS), I have not worried
2572about it.
2573
2574=back
2575
2576=head1 KNOWN BUGS
2577
2578=over 4
2579
2580=item Daylight Savings Times
2581
2582Date::Manip does not handle daylight savings time, though it does handle
2583timezones to a certain extent. Converting from EST to PST works fine.
2584Going from EST to PDT is unreliable.
2585
2586The following examples are run in the winter of the US East coast (i.e.
2587in the EST timezone).
2588
2589 print UnixDate(ParseDate("6/1/97 noon"),"%u"),"\n";
2590 => Sun Jun 1 12:00:00 EST 1997
2591
2592June 1 EST does not exist. June 1st is during EDT. It should print:
2593
2594 => Sun Jun 1 00:00:00 EDT 1997
2595
2596Even explicitly adding the timezone doesn't fix things (if anything, it
2597makes them worse):
2598
2599 print UnixDate(ParseDate("6/1/97 noon EDT"),"%u"),"\n";
2600 => Sun Jun 1 11:00:00 EST 1997
2601
2602Date::Manip converts everything to the current timezone (EST in this case).
2603
2604Related problems occur when trying to do date calculations over a timezone
2605change. These calculations may be off by an hour.
2606
2607Also, if you are running a script which uses Date::Manip over a period of
2608time which starts in one time zone and ends in another (i.e. it switches
2609form Daylight Savings Time to Standard Time or vice versa), many things may
2610be wrong (especially elapsed time).
2611
2612I hope to fix these problems in a future release so that it would convert
2613everything to the current zones (EST or EDT).
2614
2615=back
2616
2617=head1 BUGS AND QUESTIONS
2618
2619If you find a bug in Date::Manip, please send it directly to me (see the
2620AUTHOR section below) rather than posting it to one of the newsgroups.
2621Although I try to keep up with the comp.lang.perl.* groups, all too often I
2622miss news (flaky news server, articles expiring before I caught them, 1200
2623articles to wade through and I missed one that I was interested in, etc.).
2624
2625When filing a bug report, please include the following information:
2626
2627 o The version of Date::Manip you are using. You can get this by using
2628 the script:
2629
2630 use Date::Manip;
2631 print &DateManipVersion(),"\n";
2632
2633 o The output from "perl -V"
2634
2635If you have a problem using Date::Manip that perhaps isn't a bug (can't
2636figure out the syntax, etc.), you're in the right place. Go right back to
2637the top of this man page and start reading. If this still doesn't answer
2638your question, mail me (again, please mail me rather than post to the
2639newsgroup).
2640
2641=head1 YEAR 2000
2642
2643In hindsight, the fact that I've only been asked once (so far) if Date::Manip
2644is year 2000 compliant surprises me a bit. Still, as 2000 approaches and
2645this buzzword starts flying around more and more frantically, other's might
2646follow suit, so this section answers the question.
2647
2648Is Date::Manip year 2000 compliant?
2649
2650This question is largely meaningless. Date::Manip is basically just a
2651parser. You give it a date and it'll manipulate it. Date::Manip does
2652store the date internally as a 4 digit year, and performs all operations
2653using this internal representation, so I will state that Date::Manip is
2654CAPABLE of writing Y2K compliant code.
2655
2656But Date::Manip is simply a library. If you use it correctly, your code
2657can be Y2K compliant. If you don't, your code may not be Y2K compliant.
2658
2659The bottom line is this:
2660
2661 Date::Manip is a library that is capable of being used to write Y2K
2662 compliant code. It may also be used to write non-Y2K compliant code.
2663
2664 If your code is NOT Y2K compliant, it is NOT due to any deficiency in
2665 Date::Manip. Rather, it is due to poor programming on the part of the
2666 person using Date::Manip.
2667
2668For an excellent treatment of the Y2K problem, see the article by Tom
2669Christiansen at:
2670
2671 http://language.perl.com/news/y2k.html
2672
2673A slightly better question is "Is Perl year 2000 compliant"? This is
2674covered in the perl FAQ (section 4) and in the article by Tom Crhistiansen.
2675
2676The best question is "For what dates is Date::Manip useful?" It definitely
2677can't handle BC dates, or dates past Dec 31, 9999. So Date::Manip works
2678during the years 1000 to 9999.
2679
2680In practical terms however, Date::Manip deals with the Gregorian calendar,
2681and is therefore useful in the period that that calendar has been, or will
2682be, in effect. The Gregorian calendar was first adopted by the Catholic
2683church in 1582, but some countries were still using the Julian calendar as
2684late as the early part of the 20th century. Also, at some point (probably
2685no earlier than the year 3000 and possibly much later), the Gregorian
2686system is going to have to be modified slightly since the current system of
2687leap years is off by a few seconds a year. So... in practical terms,
2688Date::Manip is _probably_ useful from 1900 to 3000.
2689
2690One other note is that Date::Manip will NOT handle 3 digit years. So, if
2691you store the year as an offset from 1900 (which is 2 digits now, but will
2692become 3 digits in 2000), these will NOT be parsable by Date::Manip.
2693
2694=head1 VERSION NUMBERS
2695
2696A note about version numbers.
2697
2698Prior to version 5.00, Date::Manip was distributed as a perl4 library.
2699There were no numbering conventions in place, so I used a simple
2700MAJOR.MINOR numbering scheme.
2701
2702With version 5.00, I switched to a perl5 module and at that time switched
2703to the perl5 numbering convention of a major version followed by a 2 digit
2704minor version.
2705
2706As of 5.41/5.42, all versions released to CPAN will be even numbered. Odd
2707numbered will be development versions available from my web site. For
2708example, after 5.40 was released, I started making changes, and called
2709the development version 5.41. When released to CPAN, it was called 5.42.
2710I may add a third digit to development versions (i.e. 5.41.9) to keep
2711track of important changes in the development version.
2712
2713=head1 ACKNOWLEDGMENTS
2714
2715There are many people who have contributed to Date::Manip over the years
2716that I'd like to thank. The most important contributions have come in the
2717form of suggestions and bug reports by users. I have tried to include the
2718name of every person who first suggested each improvement or first reported
2719each bug. These are included in the HISTORY file in the Date::Manip
2720distribution in the order the changes are made. The list is simply too
2721long to appear here, but I appreciate their help.
2722
2723A number of people have made suggestions or reported bugs which are not
2724mentioned in the HISTORY file. These include suggestions which have not
2725been implemented and people who have made a suggestion or bug report which
2726has already been suggested/reported by someone else. For those who's
2727suggestions have not yet been implemented, they will be added to the
2728HISTORY file when (if) their suggestions are implemented. For everyone
2729else, thank you too. I'd much rather have a suggestion made twice than not
2730at all.
2731
2732Thanks to Alan Cezar and Greg Schiedler for paying me to implement the
2733Events_List routine. They gave me the idea, and were then willing to pay
2734me for my time to get it implemented quickly.
2735
2736I'd also like a couple of authors. Date::Manip has recently been getting
2737some really good press in a couple of books. Since no one's paying me to
2738write Date::Manip, seeing my module get a good review in a book written by
2739someone else really makes my day. My thanks to Nate Padwardhan and Clay
2740Irving (Programming with Perl Modules -- part of the O'Reilly Perl Resource
2741Kit); and Tom Christiansen and Nathan Torkington (The Perl Cookbook).
2742Also, thanks to any other authors who've written about Date::Manip who's
2743books I haven't seen.
2744
2745=head1 AUTHOR
2746
2747Sullivan Beck (sbeck@cpan.org)
2748
2749You can always get the newest beta version of Date::Manip (which may fix
2750problems in the current CPAN version... and may add others) from my home
2751page:
2752
2753http://www.cise.ufl.edu/~sbeck/
2754
2755=cut