1Date::Manip::Delta(3) User Contributed Perl DocumentationDate::Manip::Delta(3)
2
3
4
6 Date::Manip::Delta - Methods for working with deltas
7
9 use Date::Manip::Delta;
10 $date = new Date::Manip::Delta;
11
13 This module contains functions useful in parsing and manipulating
14 deltas. As used in this module, a delta refers only to the amount of
15 time elapsed. It includes no information about a starting or ending
16 time.
17
18 There are several concepts involved in understanding the properties of
19 a delta.
20
21 standard and business delta
22 Deltas can refer to changes in either the full calendar (standard
23 deltas), or they can refer to a business calendar.
24
25 With a business delta, non-business days are ignored. Typically,
26 this includes holidays and weekends. In addition, the part of the
27 day outside of business hours is also ignored, so a day may only
28 run from 08:00 to 17:00 and everything outside of this is ignored.
29
30 The length of a work day is usually not 24 hours. It is defined by
31 the start and end of the work day and is set using the config
32 variables: WorkDayBeg and WorkDayEnd (WorkDay24Hr may be used to
33 specify a 24-hour work day). The work week is defined using the
34 config variables: WorkWeekBeg and WorkWeekEnd.
35
36 Daylight saving time will have no impact on business calculations
37 because time changes occur at night (usually on the weekends)
38 outside of business hours. As such, they are ignored in business
39 calculations.
40
41 fields
42 A delta consists of 7 fields: years, months, weeks, days, hours,
43 minutes, and seconds, usually expressed as a colon-separated
44 string. For example:
45
46 1:2:3:4:5:6:7
47
48 refers to an elapsed amount of time 1 year, 2 months, 3 weeks, 4
49 days, 5 hours, 6 minutes, and 7 seconds long.
50
51 normalized
52 A delta can be normalized or not. A normalized delta has values
53 which have been made consistent with the type of data they
54 represent. For example, a delta of:
55
56 0:0:0:0:0:10:70
57
58 is not normalized since 70 seconds is better expressed as 1 minute
59 10 seconds. The normalized form of this delta would be:
60
61 0:0:0:0:0:11:10
62
63 By default, deltas are converted to a normalized form in most
64 functions that create/modify a delta, but this can be overridden.
65
66 sets of fields
67 When normalizing a delta, fields are grouped together in sets where
68 the exact relationship is known between all fields in the set.
69
70 For example, there is an exactly known relationship between seconds
71 and minutes (Date::Manip ignores leap seconds, so there are always
72 60 seconds in a minute), so they will be in one set.
73
74 Likewise, the relationship between years and months is known, so
75 they will be in one set. There is no known relationship between
76 months and weeks though, so they will be in separate sets.
77
78 A standard (i.e. non-business) delta contains 3 sets of fields:
79
80 approximate: year, month
81 semi-exact: week, day
82 exact: hour, minute, second
83
84 The following known relationships exist:
85
86 1 year = 12 months
87 1 week = 7 days
88 1 hour = 60 minutes
89 1 minute = 60 seconds
90
91 The following semi-approximate relationships are used to link the
92 semi-exact and exact fields when required:
93
94 1 day = 24 hours
95
96 The following approximate relationship is used to link the
97 approximate fields to the semi-exact fields when required:
98
99 1 year = 365.2425
100
101 Business deltas differ slightly, Since daylight saving times
102 effects are ignored, the length of the work day is constant, but
103 due to there being holidays, the length of a week is not known, so
104 a business delta has the following sets of fields:
105
106 approximate: year, month
107 semi-exact: week
108 exact: day, hour, minute, second
109
110 and the relationships used are:
111
112 1 year = 12 months
113 1 day = length of business day
114 1 hour = 60 minutes
115 1 minute = 60 seconds
116
117 The semi-approximate relationship may be used to link the semi-
118 approximate and exact fields together:
119
120 1 week = X (length of business week in days)
121
122 and the following approximate relationship may be used:
123
124 1 year = X/7 * 365.2425
125
126 When normalizing a delta, no data from one set will ever be mixed
127 with data from another set.
128
129 As a result, the following delta is normalized:
130
131 0:3:8:0:0:0:0
132
133 Although 8 weeks is clearly more than 1 month, we don't know the
134 relationship between the two, so they don't mix.
135
136 exact, semi-exact, and approximate deltas
137 An exact delta is one which every value is of an exactly known
138 length (i.e. it only includes the exact fields listed above).
139
140 A semi-exact delta is a delta which includes the exact fields as
141 well as semi-exact ones.
142
143 An approximate delta can include any of the fields.
144
145 So, the delta:
146
147 0:3:8:0:0:0:0
148
149 is approximate. The delta:
150
151 0:0:0:0:30:0:0
152
153 is exact. The delta:
154
155 0:0:0:1:30:0:0
156
157 is semi-exact (if it is non-business) or exact (if it is business).
158
159 The term "semi-exact" needs a little explanation. Date::Manip
160 tries to do things in a way which humans think of them. It is
161 immediately recognized that the approximate fields are of
162 completely unknown length, and the exact fields are of known
163 length. The "semi-exact" fields are termed such since humans have a
164 way of looking at them which is consistent, even if it is not
165 exact.
166
167 For example, a day is thought of as the same wall clock time on two
168 successive days, so from noon on one day to noon the next day is
169 one day. Usually that is 24 hours (for standard deltas), but if
170 you cross a daylight saving time change, it might be 23 or 25 hours
171 (or something different if a very irregular time change occurs).
172 So where possible, in a standard delta, a day field will change the
173 date, but leave the time alone.
174
175 Likewise, a business week is thought of as 7 days (i.e. Wednesday
176 to Wednesday) regardless of whether there was a holiday in there.
177
178 signs
179 Each field has a sign associated with it. For example, the delta "1
180 year ago" is written as:
181
182 -1:0:0:0:0:0:0
183
184 The sign of any field is optional, and if omitted, it is the same
185 as the next higher field. So, the following are identical:
186
187 +1:2:3:4:5:6:7
188 +1:+2:+3:+4:+5:+6:+7
189
190 Since there is no mixing of data between sets of fields, you can
191 end up with a delta with as many as four signs. So, the following
192 is a fully normalized business delta:
193
194 +1:0:-3:+3:1:0:0
195
196 fractional values
197 Fractional fields are allowed such as:
198
199 1.25 days
200 1.1 years
201
202 When parsing a delta with fractional fields, the delta will ALWAY
203 be normalized using the exact, semi-exact, and approximate
204 relationships described above.
205
206 For example, for a non-business delta, a delta of 1.1 years will
207 use the following relationships:
208
209 1 year = 365.2425 days
210 1 year = 12 months
211 1 day = 24 hours
212
213 Since the delta includes approximate fields, as much of the 1.1
214 year portion of the delta will be stored in the approximate fields
215 as possible.
216
217 Using the above approximate relationships, we can see that:
218
219 1 month = 365.2425/12 days = 30.436875 days
220
221 so
222
223 1.1 years
224 = 1 year, 1.2 months
225 = 1 year, 1 month, 6.087375 days
226 = 1 year, 1 month, 6 days, 2 hours, 5 minutes, 49 seconds
227
228 Fractional seconds will be discarded (no rounding).
229
231 new
232 new_config
233 new_date
234 new_delta
235 new_recur
236 base
237 tz
238 is_date
239 is_delta
240 is_recur
241 config
242 err Please refer to the Date::Manip::Obj documentation for these
243 methods.
244
245 parse
246 $err = $delta->parse($string [,$business] [,$no_normalize]);
247
248 This takes a string and parses it to see if it is a valid delta. If
249 it is, an error code of 0 is returned and $delta now contains the
250 value of the delta. Otherwise, an error code of 1 is returned and
251 an error condition is set in the delta.
252
253 A valid delta is in one of two forms: compact or expanded.
254
255 The compact format is a colon separated list of numbers (with
256 optional signs):
257
258 Examples:
259 0:0:0:0:4:3:-2
260 +4:3:-2
261 +4::3
262
263 In the compact format, from 1 to 7 of the fields may be given. For
264 example D:H:MN:S may be given to specify only four of the fields.
265 No spaces may be present in the compact format. It is allowed to
266 omit some of the fields. For example 5::3:30 is valid. In this
267 case, missing fields default to the value 0.
268
269 The expanded format has the fields spelled out in some language
270 specific form:
271
272 Examples:
273 +4 hours +3mn -2second
274 + 4 hr 3 minutes -2
275 4 hour + 3 min -2 s
276 4 hr 2 s
277
278 A field in the expanded format has an optional sign, a number, and
279 a string specifying the type of field. If the sign is absent, it
280 defaults to the sign of the next larger element. So the following
281 are equivalent:
282
283 -4 hr 3 min 2 sec
284 -4 hr -3 min -2 sec
285
286 The valid strings describing each of the fields is contained in
287 "Delta field names" section of the appropriate
288 Date::Manip::Lang::<LANGUAGE> document. Refer to the
289 Date::Manip::Lang document for a list of languages.
290
291 For example, for English, the document is
292 Date::Manip::Lang::English and the field names include strings
293 like:
294
295 y: y, yr, year, years
296 m: m, mon, month, months
297 w: w, wk, ws, wks, week, weeks
298 d: d, day, days
299 h: h, hr, hour, hours
300 mn: mn, min, minute, minutes
301 s: s, sec, second, seconds
302
303 This list may not be complete. You should refer to the language
304 document for the full list.
305
306 The "seconds" string may be omitted. The sign, number, and string
307 may all be separated from each other by any amount of whitespace.
308 The string specifying the unit must be separated from a following
309 number by whitespace or a comma, so the following example will NOT
310 work:
311
312 4hours3minutes
313
314 At minimum, it must be expressed as:
315
316 4hours 3minutes
317 4 hours, 3 minutes
318
319 In the the expanded format, all fields must be given in the order:
320 Y M W D H MN S. Any number of them may be omitted provided the
321 rest remain in the correct order. Numbers may be spelled out, so
322
323 in two weeks
324 in 2 weeks
325
326 both work.
327
328 Most languages also allow a word to specify whether the delta is an
329 amount of time after or before a fixed point. In English, the word
330 "in" refers to a time after a fixed point, and "ago" refers to a
331 point before a fixed point. So, the following deltas are
332 equivalent:
333
334 1:0:0:0:0:0:0
335 in 1 year
336
337 and the following are equivalent
338
339 -1:0:0:0:0:0:0
340 1 year ago
341
342 The word "in" is completely ignored. The word "ago" has the affect
343 of reversing all signs that appear in front of the components of
344 the delta. In other words, the following two strings are
345 identical:
346
347 -12 yr 6 mon ago
348 +12 yr +6 mon
349
350 (don't forget that there is an implied minus sign in front of the 6
351 in the first string because when no sign is explicitly given, it
352 carries the previously entered sign).
353
354 The in/ago words only apply to the expanded format, so the
355 following is invalid:
356
357 1:0:0 ago
358
359 A delta may be standard (non-business) or business. By default, a
360 delta is treated as a non-business delta, but this can be changed
361 in two different ways.
362
363 The first way to make a delta be business is to pass in the 2nd
364 argument to the function. The $business argument may be a string
365 'standard' or 'business' to explicitly set the type of delta.
366 Alternately, any non-zero value for $business will force the delta
367 to be a business delta.
368
369 So the following are identical:
370
371 $delta->parse($string,'business');
372 $delta->parse($string,1);
373
374 and the following are identical:
375
376 $delta->parse($string);
377 $delta->parse($string,'standard');
378 $delta->parse($string,0);
379
380 The second way to specify whether a delta is business or non-
381 business is to include a key word in the string that is parsed.
382 When this is done, these strings override any value of the
383 $business argument.
384
385 Most languages include a word like "business" which can be used to
386 specify that the resulting delta is a business delta or a non-
387 business delta. Other languages have equivalent words. The
388 placement of the word is not important. Also, the "business" word
389 can be included with both types of deltas, so the following are
390 valid and equivalent:
391
392 in 4 hours business
393 4:0:0 business
394 business 0:0:0:0:4:0:0
395
396 There are also words "exact" or "approximate" which may be included
397 in the delta for backward compatibility. However, they will be
398 ignored. The accuracy of delta (exact, semi-exact, approximate)
399 will be determined only by what fields are present in the delta.
400
401 When a delta is parsed, it is automatically normalized, unless the
402 $no_normalize argument is passed in. It can be the string
403 'nonormalize' or any non-zero value. If passing it as a non-zero
404 value, the $business argument MUST be included (though it can be
405 zero) in order to avoid ambiguity.
406
407 So the following are equivalent:
408
409 $delta->parse($string,'nonormalize');
410 $delta->parse($string,$business,1);
411
412 input
413 $str = $delta->input();
414
415 This returns the string that was parsed to form the delta.
416
417 set
418 $err = $delta->set($field,$val [,$no_normalize]);
419
420 This explicitly sets one or more fields in a delta.
421
422 $field can be any of the following:
423
424 $field $val
425
426 delta [Y,M,W,D,H,MN,S] sets the entire delta
427 business [Y,M,W,D,H,MN,S] sets the entire delta
428 standard [Y,M,W,D,H,MN,S] sets the entire delta
429 y YEAR sets one field
430 M MONTH
431 w WEEK
432 d DAY
433 h HOUR
434 m MINUTE
435 s SECOND
436
437 mode business, standard
438
439 An error is returned if an invalid value is passed in.
440
441 When setting the entire delta with "business" or "normal", it flags
442 the delta as a business or non-business delta respectively. When
443 setting the entire delta with "delta", the flag is left unchanged.
444 Also, when setting the entire delta, signs are not carried from one
445 field to another.
446
447 By default, a delta is normalized, but passing $no_normalize as any
448 true value, this will not be done.
449
450 If $no_normalize is not passed in, the current value for the delta
451 (which defaults to 0) will be used.
452
453 For backwards compatibility, 'normal' can be used in place of
454 'standard', both as $field or as $val.
455
456 printf
457 $out = $delta->printf($in);
458 @out = $delta->printf(@in);
459
460 This takes a string or list of strings which may contain any number
461 of special formatting directives. These directives are replaced
462 with information contained in the delta. Everything else in the
463 string is returned unmodified.
464
465 A directive always begins with '%'. They are described in the
466 section below in the section PRINTF DIRECTIVES.
467
468 calc
469 $date2 = $delta->calc($date1 [,$subtract]);
470 $delta3 = $delta1->calc($delta2 [,$subtract]);
471
472 Please refer to the Date::Manip::Calc documentation for details.
473
474 type
475 $flag = $delta->type($op);
476
477 This tests to see if a delta is of a certain type. $op can be;
478
479 business : returns 1 if it is a business delta
480 standard : returns 1 if it is a standard (non-business delta)
481
482 exact : returns 1 if it is exact
483 semi : returns 1 if it is semi-exact
484 approx : returns 1 if it is approximate
485
486 value
487 $val = $delta->value();
488 @val = $delta->value();
489
490 This returns the value of the delta. In scalar context, it returns
491 the printable string (equivalent to the printf directive '%Dt'). In
492 list context, it returns a list of fields.
493
494 An empty string is returned if there is no valid delta stored in
495 $delta.
496
497 convert
498 $delta->convert($to);
499
500 This converts a delta from one type to another. $to can be
501 'exact', 'semi', or 'approx'. The conversion uses the approximate
502 relationships listed above to convert the delta.
503
504 For example, if the exact non-business delta $delta contains:
505
506 0:0:0:0:44:0:0
507
508 then the following call:
509
510 $delta->convert('semi')
511
512 would produce the semi-exact delta:
513
514 0:0:0:1:20:0:0
515
516 The result will always be normalized, and will be strictly positive
517 or negative (i.e. all fields will have the same sign).
518
519 This function can be used to take an exact delta and turn it into a
520 semi-exact delta (with a day being treated as 24 hours in non-
521 business mode).
522
523 There is currently no support for converting business to non-
524 business (or vice-versa).
525
526 cmp
527 $flag = $delta1->cmp($delta2);
528
529 This compares two deltas (using the approximate relationships
530 listed above) and returns -1, 0, or 1 which could be used to sort
531 them by length of time.
532
533 Both deltas must be valid, and both must be either business or non-
534 business deltas. They do not need to be the same out of exact,
535 semi-exact, and approximate.
536
537 undef will be returned if either delta is invalid, or you try to
538 compare a business and non-business delta.
539
541 The following printf directives are replaced with information from the
542 delta. Directives may be replaced by the values of a single field in
543 the delta (i.e. the hours or weeks field), the value of several fields
544 expressed in terms of one of them (i.e. the number of years and months
545 expressed in terms of months), or the directive may format either the
546 entire delta, or portions of it.
547
548 Simple directives
549 These are directives which print simple characters. Currently, the
550 only one is:
551
552 %% Replaced by a single '%'
553
554 As an example:
555
556 $delta->printf('|%%|');
557 => |%|
558
559 Directives to print out a single field
560 The following directive is used to print out the value of a single
561 field. Spaces are included here for clarity, but are not in the
562 actual directive.
563
564 % [+] [pad] [width] Xv
565
566 Here, X is one of (y,M,w,d,h,m,s). The directive will print out the
567 value for that field (in the normalized delta).
568
569 If a '+' is included immediately after the '%', a sign will always
570 be included. By default, only negative values will include a sign.
571
572 'width' is any positive integer (without a sign). If 'width' is
573 included, it sets the length of the output string (unless the
574 string is already longer than that, in which case the 'width' is
575 ignored).
576
577 If 'pad' is included, it may be the character '<', '>', or '0'. It
578 will be ignored unless 'width' is included. If the formatted delta
579 field is shorter than 'width', it will be padded with spaces on the
580 left (if 'pad' is '<'), or right (if 'pad' is '>'), or it will be
581 padded on the left (after any sign) with zeroes (if 'pad' is '0').
582
583 In the following examples, $delta contains the delta: 1:2:3:4:5:6:7
584
585 $delta->printf('|Month: %Mv|');
586 => |Month: 2|
587
588 $delta->printf('|Day: %+05dv|');
589 => |Day: +0004|
590
591 $delta->printf('|Day: %+<5dv|');
592 => |Day: +4|
593
594 $delta->printf('|Day: %>5sv|');
595 => |Day: 7 |
596
597 Directives to print out several fields in terms of one of them
598 The following directive is used to print out the value of several
599 different fields, expressed in terms of a single field.
600
601 % [+] [pad] [width] [.precision] XYZ
602
603 Here, X, Y, and Z are each one of (y,M,w,d,h,m,s). The directive
604 will print out the value for fields Y through Z expressed in terms
605 of field X.
606
607 Y must come before Z in the sequence (y,M,w,d,h,m,s) or it can be
608 the same as Z.
609
610 So, to print the day and hour fields in terms of seconds, use the
611 directive:
612
613 %sdh
614
615 Any time all of X, Y, and Z are from a single set of fields, exact
616 relationships are used.
617
618 If the X, Y, and Z fields do not all belong to the same set of
619 fields, approximate relationships are used.
620
621 For non-business deltas, an approximate relationship is needed to
622 link the Y/M part of the delta to the W/D part and a semi-
623 approximate relationship is needed to link the W/D part with the
624 H/MN/S part. These relationships are:
625
626 1 day = 24 hours
627 1 year = 365.2425
628
629 For business deltas, the approximate and semi-approximate
630 relationships used to link the fields together are:
631
632 1 week = X (length of business week in days)
633 1 year = X/7 * 365.2425
634
635 For business deltas, the length of the day is defined using
636 WorkDayStart and WorkDayEnd. For non-business deltas, a day is 24
637 hours long (i.e. daylight saving time is ignored).
638
639 If 'precision' is included, it is the number of decimal places to
640 print. If it is not included, but 'width' is included, precision
641 will be set automatically to display the maximum number of decimal
642 places given 'width'.
643
644 If 'pad' is included, it may be the character '<', '>', or '0', and
645 is used in the same way as printing out a single field.
646
647 In the following examples, $delta contains the delta: 1:2:3:4:5:6:7
648
649 $delta->printf('|%.4Myw|');
650 => |14.6900|
651 1 year, 2 months, 3 weeks is approximately
652 14.6900 months
653
654 Directives to print out portions of the delta
655 The following directives may be used to print out some or all of a
656 delta.
657
658 % [+] [pad] [width] Dt
659 % [+] [pad] [width] DXY
660
661 The first directive will print out the entire delta.
662
663 The second will print out the delta from the X to Y fields
664 inclusive (where X and Y are each one of (y,M,w,d,h,m,s) and X must
665 come before Y in the sequence).
666
667 'pad' is optional and can be either '<' or '>' meaning to pad on
668 the left or right with spaces. It defaults to '<'.
669
670 If a '+' is included immediately following the '%', every field
671 will have a sign attached. Otherwise, only the leftmost field in
672 each set of fields will include a sign.
673
674 $delta->printf('|%Dt|');
675 => |+1:2:+3:+4:5:6:7|
676
677 $delta->printf('|%+Dyd|');
678 => |+1:+2:+3:+4|
679
681 None known.
682
684 Please refer to the Date::Manip::Problems documentation for information
685 on submitting bug reports or questions to the author.
686
688 Date::Manip - main module documentation
689
691 This script is free software; you can redistribute it and/or modify it
692 under the same terms as Perl itself.
693
695 Sullivan Beck (sbeck@cpan.org)
696
697
698
699perl v5.26.3 2017-03-01 Date::Manip::Delta(3)