1Pcalendar(3) User Contributed Perl Documentation Pcalendar(3)
2
3
4
6 Date::Pcalendar - Calendar objects for different holiday schemes
7
9 There is more than one way to do it - this is just one of them!
10
12 Basically, Date::Pcalendar is just a caching proxy class for
13 Date::Pcalendar::Year objects, which are embedded in each
14 Date::Pcalendar object.
15
16 However, and in contrast to Date::Pcalendar::Year methods,
17 Date::Pcalendar methods permit calculations spanning an arbitrary
18 number of years, without loss of efficiency.
19
20 So you should usually use Date::Pcalendar and not
21 Date::Pcalendar::Year, since that way you don't have to worry about
22 calculations crossing year boundaries.
23
24 Note however that Date::Pcalendar and Date::Pcalendar::Year can only
25 deal with years lying within the range [1583..2299].
26
28 use Date::Pcalendar::Profiles qw( $Profiles );
29 use Date::Pcalendar;
30
31 $calendar_US_AZ = Date::Pcalendar->new( $Profiles->{'US-AZ'} [,LANG[,WEEKEND]] );
32 $calendar_DE_SN = Date::Pcalendar->new( $Profiles->{'DE-SN'} [,LANG[,WEEKEND]] );
33
34 $year_2000_US_AZ = $calendar_US_AZ->year( 2000 );
35 $year_2001_DE_SN = $calendar_DE_SN->year( 2001 );
36
37 @years = $calendar->cache_keys(); # returns list of year numbers
38 @years = $calendar->cache_vals(); # returns list of year objects
39
40 $calendar->cache_clr();
41 $calendar->cache_add(YEAR|DATE,...);
42 $calendar->cache_del(YEAR|DATE,...);
43
44 $index = $calendar->date2index(YEAR,MONTH,DAY|DATE);
45
46 @names = $calendar->labels(YEAR,MONTH,DAY|DATE);
47 @holidays = $calendar->labels();
48 $holidays = $calendar->labels();
49
50 @dates = $calendar->search(PATTERN);
51 $dates = $calendar->search(PATTERN);
52
53 $hashref = $calendar->tags(YEAR,MONTH,DAY|DATE);
54
55 $days = $calendar->delta_workdays(YEAR1,MONTH1,DAY1|DATE1
56 ,YEAR2,MONTH2,DAY2|DATE2
57 ,FLAG1,FLAG2);
58
59 ($date,$rest) = $calendar->add_delta_workdays(YEAR,MONTH,DAY|DATE
60 ,DELTA);
61 $date = $calendar->add_delta_workdays(YEAR,MONTH,DAY|DATE
62 ,DELTA);
63
64 $flag = $calendar->is_full(YEAR,MONTH,DAY|DATE);
65 $flag = $calendar->is_half(YEAR,MONTH,DAY|DATE);
66 $flag = $calendar->is_work(YEAR,MONTH,DAY|DATE);
67
69 Note that whenever a year number, a date, a time or a combined date and
70 time are expected as input parameters by one of the methods of this
71 class, you can always pass a Date::Pcalc[::Object] date object or an
72 array reference (of an array of appropriate length) instead!
73
74 See Date::Pcalc::Object(3) for more details.
75
76 So instead of calling a given method like this:
77
78 $object->method1( $year,$month,$day );
79 $object->method2( $year1,$month1,$day1, $year2,$month2,$day2 );
80 $object->method3( $year1, $year2, $year3 );
81
82 You can also call it like so:
83
84 $object->method1( $date );
85 $object->method1( [1964,1,3] );
86
87 $object->method2( $year1,$month1,$day1, $date2 );
88 $object->method2( $date1, $year2,$month2,$day2 );
89 $object->method2( $date1, $date2 );
90 $object->method2( $year1,$month1,$day1, [2001,3,17] );
91 $object->method2( [1964,1,3], $year2,$month2,$day2 );
92 $object->method2( [1964,1,3], [2001,3,17] );
93 $object->method2( $date1, [2001,3,17] );
94 $object->method2( [1964,1,3], $date2 );
95
96 $object->method3( $year1, $date2, [2001,3,17] );
97
98 And similarly if a time or a combined date and time are expected.
99
100 If you substitute an expected year number by an anonymous array (this
101 is the recommended way of writing date constants, for increased
102 readability of your programs), it must contain three values,
103 nevertheless (otherwise the use of an anonymous array would be
104 pointless).
105
106 Don't confuse year numbers and their substitutes (a date object or an
107 array reference) with Date::Pcalendar::Year objects, which are a
108 totally different thing!
109
110 But incidentally ":-)", you may also pass a Date::Pcalendar::Year
111 object whenever a year number is expected. However, and perhaps against
112 your expectations at times, especially in conjunction with the method
113 "cache_add()", only the year number from that object will be used, not
114 the year object itself (the year object in question might be using the
115 wrong profile!).
116
117 Moreover, whenever a method of this class returns a date, it does so by
118 returning a Date::Pcalc[::Object] date object.
119
121 • "$calendar = Date::Pcalendar->new(PROFILE[,LANG[,WEEKEND]]);"
122
123 The first argument must be the reference of a hash, which contains a
124 holiday scheme or "profile" to be used in all calculations involving
125 the new calendar object.
126
127 The second argument is optional, and must consist of the valid name
128 or number of a language as provided by the Date::Pcalc(3) module if
129 given.
130
131 After the second argument, a list of day numbers which will
132 constitute the "weekend" can optionally be specified, where 1=Monday,
133 2=Tuesday, 3=Wednesday, 4=Thursday, 5=Friday, 6=Saturday and
134 7=Sunday.
135
136 If no values are given, 6 and 7 (Saturday and Sunday) are
137 automatically taken as default.
138
139 If values outside of the range 1..7 are given, they will be ignored.
140
141 This can be used to switch off this feature and to have no regularly
142 recurring holidays at all when for instance a zero is given.
143
144 See Date::Pcalendar::Profiles(3) and Date::Pcalendar::Year(3) for
145 more details about these arguments and about how to roll your own
146 calendar profiles.
147
148 The method creates a new calendar object for a given profile, i.e., a
149 given location and its scheme of holidays (or a scheme of your own).
150
151 This calendar object is a caching proxy object; it stores the
152 reference of the given profile and contains a hash (the cache) of
153 Date::Pcalendar::Year objects.
154
155 • "$year = $calendar->year(YEAR|DATE);"
156
157 This method returns a Date::Pcalendar::Year object for the given year
158 and the profile that was associated with the given calendar object.
159
160 If the cache in the given calendar object already contains an object
161 for the requested year, the corresponding object reference is simply
162 returned.
163
164 If not, a new Date::Pcalendar::Year object is created using the
165 profile that has been associated with the given calendar object. The
166 new Date::Pcalendar::Year object is then stored in the calendar
167 object's cache and its object reference is returned.
168
169 A fatal "given year out of range" error will occur if the given year
170 number lies outside the valid range of [1583..2299].
171
172 • "@years = $calendar->cache_keys();"
173
174 This method returns the list of YEAR NUMBERS of the
175 Date::Pcalendar::Year objects contained in the given calendar
176 object's cache.
177
178 • "@years = $calendar->cache_vals();"
179
180 This method returns the list of OBJECT REFERENCES of the
181 Date::Pcalendar::Year objects contained in the given calendar
182 object's cache.
183
184 • "$calendar->cache_clr();"
185
186 This method clears the entire cache of the given calendar object (by
187 destroying the cache hash and creating a new one).
188
189 • "$calendar->cache_add(YEAR|DATE,...);"
190
191 Roughly, this method is a shortcut for
192
193 for $year (@list)
194 {
195 $calendar->year($year);
196 }
197
198 • "$calendar->cache_del(YEAR|DATE,...);"
199
200 This method removes the Date::Pcalendar::Year objects whose year
201 numbers are given from the cache of the given calendar object.
202
203 Year numbers for which the calendar object's cache doesn't contain an
204 entry are simply ignored.
205
206 • "$index = $calendar->date2index(YEAR,MONTH,DAY|DATE);"
207
208 This method converts a given date into the number of the day in that
209 year (this is sometimes also referred to as the "julian" date), i.e.,
210 a number between 0 (for January 1st) and the number of days in the
211 given year minus one, i.e., 364 or 365 (for December 31st).
212
213 You may need this in order to access the bit vectors returned by the
214 Date::Pcalendar::Year methods "vec_full()", "vec_half()" and
215 "vec_work()".
216
217 If the Date::Pcalendar::Year object for the given YEAR is not in the
218 $calendar's cache yet, it will be created and added.
219
220 An exception ("invalid date") is thrown if the given arguments do not
221 constitute a valid date, or ("given year out of range [1583..2299]")
222 if the given year lies outside of the permitted range.
223
224 • "@names = $calendar->labels(YEAR,MONTH,DAY|DATE);"
225
226 "@holidays = $calendar->labels();"
227
228 "$holidays = $calendar->labels();"
229
230 If any arguments are given, they are supposed to represent a date. In
231 that case, a list of all labels (= names of holidays) associated with
232 that date are returned. The first item returned is always the name of
233 the day of week for that date. The corresponding year object for the
234 given date's year is added to the calendar's cache first if
235 necessary.
236
237 If no arguments are given, the list of all available labels in all
238 years that have previously been accessed in the given calendar (i.e.,
239 the years which are already in the given calendar's cache) is
240 constructed. Note that this means that the returned list will be
241 empty if there are no year objects in the given calendar's cache yet
242 (!). The returned list does NOT include any names of the days of week
243 (which would be pointless in this case).
244
245 Multiple labels are reported only once.
246
247 Usually all years have the same set of labels, so it may seem
248 superfluous to scan all the years in the cache instead of just one.
249 But there may be exceptions, because it is possible to define
250 calendar profiles which do not contain all possible holidays in every
251 year. See Date::Pcalendar::Profiles(3) and Date::Pcalendar::Year(3)
252 for more details.
253
254 In list context, the resulting list itself is returned. In scalar
255 context, the number of items in the resulting list is returned.
256
257 • "@dates = $calendar->search(PATTERN);"
258
259 "$dates = $calendar->search(PATTERN);"
260
261 This method searches through all the labels in all years that have
262 previously been accessed in the given calendar (i.e., the years which
263 are already in the given calendar's cache) and returns a list of date
264 objects with all dates whose labels match the given pattern.
265
266 (Use the methods "cache_clr()", "cache_add()" and "cache_del()" in
267 order to put the year numbers you want into the calendar object's
268 cache, or to make sure it only contains the year numbers you want to
269 search.)
270
271 Note that this is a simple, case-insensitive substring search, NOT a
272 full-fledged regular expression search!
273
274 The result is guaranteed to be sorted chronologically.
275
276 In scalar context, only the number of items in the resulting list is
277 returned, instead of the resulting list itself (as in list context).
278
279 • "$hashref = $calendar->tags(YEAR,MONTH,DAY|DATE);"
280
281 This method returns a hash reference for the given calendar and date.
282 The hash it refers to is a copy of the calendar profile's internal
283 hash which contains the names for the given date as keys and 0, 1, 2,
284 or 3 as their corresponding values meaning the following:
285
286 0 => commemorative day
287 1 => "half" holiday
288 2 => "full" holiday
289 3 => both a "half" and a "full" holiday
290
291 The value "3" should only occur if a date has been redefined by the
292 underlying profile using the same key (i.e., the same name) but with
293 a different type of holiday.
294
295 • "$days = $calendar->delta_workdays(YEAR1,MONTH1,DAY1,
296 YEAR2,MONTH2,DAY2, FLAG1,FLAG2);"
297
298 "$days = $calendar->delta_workdays(DATE1,DATE2,FLAG1,FLAG2);"
299
300 This method calculates the number of work days (i.e., the number of
301 days, but excluding all holidays) between two dates.
302
303 In other words, this method is equivalent to the "Delta_Days()"
304 function of the Date::Pcalc module, except that it disregards
305 holidays in its counting.
306
307 The two flags indicate whether the start and end dates should be
308 included in the counting (that is, of course, only in case they
309 aren't holidays), or not.
310
311 It is common, for example, that you want to know how many work days
312 are left between the current date and a given deadline.
313
314 Typically, you will want to count the current date but not the
315 deadline's date. So you would specify "true" ("1") for FLAG1 and
316 "false" ("0") for FLAG2 in order to achieve that.
317
318 In other words, a value of "true" means "including this date", a
319 value of "false" means "excluding this date".
320
321 As with the "Delta_Days()" function from the Date::Pcalc module, the
322 dates have to be given in chronological order to yield a positive
323 result. If the dates are reversed, the result will be negative.
324
325 The parameter FLAG1 is associated with the first given date, the
326 parameter FLAG2 with the second given date (regardless of whether the
327 dates are in chronological order or not).
328
329 An exception ("invalid date") is raised if either of the two date
330 arguments does not constitute a valid date.
331
332 • "($date,$rest) = $calendar->add_delta_workdays(YEAR,MONTH,DAY,
333 DELTA);"
334
335 "($date,$rest) = $calendar->add_delta_workdays(DATE,DELTA);"
336
337 "$date = $calendar->add_delta_workdays(YEAR,MONTH,DAY, DELTA);"
338
339 "$date = $calendar->add_delta_workdays(DATE,DELTA);"
340
341 This method is the equivalent of the "Add_Delta_Days()" function from
342 the Date::Pcalc module, except that it adds work days and skips
343 holidays.
344
345 In other words, you can add or subtract a number of work days "DELTA"
346 to/from a given date and get a new date as the result (as a
347 Date::Pcalc object).
348
349 You add days (i.e., you go forward in time) with a positive offset
350 "DELTA", and you subtract days (i.e., you go backwards in time) with
351 a negative offset.
352
353 Note that an exception ("invalid date") is raised if the given date
354 argument does not constitute a valid date.
355
356 In scalar context, the method just returns the resulting date object,
357 whereas in list context the method not only returns the new date, but
358 also a "rest". This rest is useful for cases in which your profile
359 contains "half" holidays, or when you add or subtract fractions of a
360 day.
361
362 Sometimes it is not possible to accomodate the requested number of
363 work days, and a rest remains.
364
365 This rest can currently only assume the value "0.0" (zero), "-0.5"
366 (minus one half) or "0.5" (one half), provided you use only integral
367 or multiples of 0.5 as offsets. A rest of zero indicates that the
368 calculation yielded an exact result. If the rest is 0.5 or -0.5, this
369 is to be interpreted as "the resulting date at 12:00 o'clock",
370 instead of as "the resulting date at 0:00 o'clock".
371
372 The rest is always positive (or zero) if the offset "DELTA" is
373 positive (or zero), and always negative (or zero) if the offset is
374 negative (or zero).
375
376 Example:
377
378 #!perl
379 use Date::Pcalendar;
380 use Date::Pcalendar::Profiles qw( $Profiles );
381 $year = shift;
382 $cal = Date::Pcalendar->new( $Profiles->{'sdm-MUC'} );
383 ($date,$rest) = $cal->add_delta_workdays($year,1,3, -3);
384 $date->date_format(1);
385 print "\$date = $date, \$rest = $rest.\n";
386 __END__
387
388 This program calculates "January 3rd of the given year minus 3 work
389 days":
390
391 > perl test.pl 2001
392 $date = 28-Dec-2000, $rest = 0.
393 > perl test.pl 2002
394 $date = 28-Dec-2001, $rest = -0.5.
395
396 Note that December 31st is a "half" holiday in 2001 for the calendar
397 profile used in this example.
398
399 You can easily verify the results above with the help of the
400 "calendar.cgi" CGI script or the "linearcal.pl" script from the
401 "examples" subdirectory in the Date::Pcalc distribution.
402
403 BEWARE that this method may currently return unexpected (i.e.,
404 contradicting the above documentation) or plain wrong results when
405 going back in time (this is a bug!).
406
407 However, it works correctly and as documented above when going
408 forward in time.
409
410 • "$flag = $calendar->is_full(YEAR,MONTH,DAY|DATE);"
411
412 This method returns "true" ("1") if the bit corresponding to the
413 given date is set in the bit vector representing "full" holidays, and
414 "false" ("0") otherwise.
415
416 I.e., the method returns "true" if the given date is a (full) holiday
417 (according to the calendar profile associated with the given calendar
418 object).
419
420 The corresponding Date::Pcalendar::Year object is created first and
421 stored in the calendar object's cache if necessary (if it's not
422 already there).
423
424 Note that you can get a reference to this bit vector (in order to use
425 this bit vector in bit vector operations) as follows:
426
427 $vec_full = $calendar->year($year)->vec_full();
428
429 The number of bits in this bit vector is the same as the number of
430 days in the given year "$year", which you can retrieve through either
431 ""$days = $vec_full->Size();"" or ""$days = $year->val_days();"".
432
433 See Date::Pcalendar::Year(3) and Bit::Vector(3) for more details.
434
435 • "$flag = $calendar->is_half(YEAR,MONTH,DAY|DATE);"
436
437 This method returns "true" ("1") if the bit corresponding to the
438 given date is set in the bit vector representing "half" holidays, and
439 "false" ("0") otherwise.
440
441 I.e., the method returns "true" if the given date is a half holiday
442 (according to the calendar profile associated with the given calendar
443 object).
444
445 Note that if a date is a "full" holiday, the "half" bit is never set,
446 even if you try to do so in your calendar profile, on purpose or by
447 accident.
448
449 The corresponding Date::Pcalendar::Year object is created first and
450 stored in the calendar object's cache if necessary (if it's not
451 already there).
452
453 Note that you can get a reference to this bit vector (in order to use
454 this bit vector in bit vector operations) as follows:
455
456 $vec_half = $calendar->year($year)->vec_half();
457
458 The number of bits in this bit vector is the same as the number of
459 days in the given year "$year", which you can retrieve through either
460 ""$days = $vec_half->Size();"" or ""$days = $year->val_days();"".
461
462 See Date::Pcalendar::Year(3) and Bit::Vector(3) for more details.
463
464 • "$flag = $calendar->is_work(YEAR,MONTH,DAY|DATE);"
465
466 This method returns "true" ("1") if the bit corresponding to the
467 given date is set in the bit vector used to perform all sorts of
468 calculations, and "false" ("0") otherwise.
469
470 The corresponding Date::Pcalendar::Year object is created first and
471 stored in the calendar object's cache if necessary (if it's not
472 already there).
473
474 BEWARE that the "work" in this method's name does NOT come from "work
475 days"!
476
477 It comes from the fact that the corresponding bit vector can be used
478 for any "work" that you need to do. In other words, it's a "work
479 space".
480
481 Therefore, this bit vector might contain about everything you could
482 imagine - including a bit pattern which marks all "work days" with
483 set bits, if it so happens!
484
485 But you better don't rely on it, unless you put the bit pattern there
486 yourself in the first place.
487
488 Note that you can get a reference to this bit vector (in order to
489 fill it with any bit pattern you like) as follows:
490
491 $vec_work = $calendar->year($year)->vec_work();
492
493 The number of bits in this bit vector is the same as the number of
494 days in the given year "$year", which you can retrieve through either
495 ""$days = $vec_work->Size();"" or ""$days = $year->val_days();"".
496
497 See Date::Pcalendar::Year(3) and Bit::Vector(3) for more details.
498
500 Date::Pcalendar::Year(3), Date::Pcalendar::Profiles(3),
501 Date::Pcalc::Object(3), Date::Pcalc(3), Date::Calc::Util(3),
502 Bit::Vector(3).
503
505 The calendar profiles included in Date::Pcalendar::Profiles(3) usually
506 do not take historical irregularities into account (even though some do
507 in order to show how this can be done), they only provide means for
508 calculating regularly recurring events (the profiles should therefore
509 not be relied upon for historical faithfulness).
510
512 The method "add_delta_workdays()" is known to produce results which are
513 sometimes off by one working day when a negative offset is used. As a
514 workaround, try to add one working day first and then subtract one
515 working day more than initially intended. See also the file
516 "examples/bug.pl" for how to do this.
517
519 This man page documents "Date::Pcalendar" version 6.1.
520
522 Steffen Beyer
523 mailto:STBEY@cpan.org
524 http://www.engelschall.com/u/sb/download/
525
527 Copyright (c) 2000 - 2009 by Steffen Beyer. All rights reserved.
528
530 This package is free software; you can redistribute it and/or modify it
531 under the same terms as Perl itself, i.e., under the terms of the
532 "Artistic License" or the "GNU General Public License".
533
534 Please refer to the files "Artistic.txt" and "GNU_GPL.txt" in this
535 distribution for details!
536
538 This package is distributed in the hope that it will be useful, but
539 WITHOUT ANY WARRANTY; without even the implied warranty of
540 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
541
542 See the "GNU General Public License" for more details.
543
544
545
546perl v5.36.0 2023-01-20 Pcalendar(3)