Date::Manip::Calc(3)
πΈ Date::Manip::Calc πΈ
okay bestie, welcome to Date::Manip::Calc(3) β straight out of the User Contributed Perl Documentation, and it's the page about date calculations. it's a big one. grab a snack. π
β¨ NAME β¨
Date::Manip::Calc β describes date calculations π
β¨ SYNOPSIS β¨
so you've got two objects (each one is either a Date::Manip::Date or a Date::Manip::Delta), and you smoosh them together to make a third object. that's the whole vibe:
$delta = $date->calc($date2 [,$subtract] [,$mode]);
$date2 = $date->calc($delta [,$subtract]);
$date2 = $delta->calc($date1 [,$subtract]);
$delta3 = $delta1->calc($delta2 [,$subtract] [,$no_normalize]);
β¨ DESCRIPTION β¨
this doc walks you through all the different kinds of calculations you can do with dates and deltas. and ngl, date calculations are so much messier than they look at first glance β which is literally why this document is huge. no cap.
here's the tea: some parts of a delta just cannot be expressed as an exact length. and that's the entire source of the drama. some examples, because seeing it hits different:
let's take two dates and figure out how much time happened between them:
Nov 3 2016 11:00:00
Dec 5 2016 12:00:00
Elapsed time: 770 hours
there's more than one way to describe that elapsed time. way number one is just to give the difference exactly. that's the exact delta β¨
an exact delta is always described in terms of hours, minutes, and seconds. periodt.
the problem?? we do not think in exact deltas. we think in terms that can't be expressed exactly. it's giving human brain.
like, most people would look at those two dates and go:
Perceived: 1 month, 2 days, 1 hour
but then look at these two dates:
Feb 3 2016 11:00:00
Mar 5 2016 12:00:00
Elapsed time: 745 hours
Perceived: 1 month, 2 days, 1 hour
some fields in a delta just don't have an exact length. a year is usually 365 days long, but sometimes it's 366. a month might be 28, 29, 30, or 31 days long. it's giving chaos. π
and maybe the most unexpected difficulty of all: days are not of constant length. most people would define a day as 24 hours, but the second you bring daylight saving time into it, that definition produces unexpected results. watch:
Nov 5, 2011 02:30 EDT
+ 24 hour
Result: Nov 6, 2011 01:30 EST
and this immediately makes most people redefine a day as the amount of time between the same wall clock time. like, the amount of time between noon one day and noon the next β regardless of daylight saving time changes.
but bestie, that definition doesn't work either. for example:
Mar 12, 2011 02:30 EST
+ 1 day (same time next day)
Result: Mar 13 02:30 EST
but that date does not exist!! π and neither does:
Result: Mar 13 02:30 EDT
an alternate calculation could be:
Nov 5, 2011 01:30 EDT
+ 1 day (same time next day)
Result: Nov 6, 01:30 EDT
Result: Nov 6, 01:30 EST
both of those results exist. so which one did you mean?? the first one is probably correct (since it is 24 hours later), but an hour later, you will have the same clock time again. iconic ambiguity, honestly.
so the "same time next day" definition doesn't work at all for some dates (during a 'spring forward' type daylight saving time transition) and is ambiguous for others (during a 'fall back' type daylight saving time transition). π«
calculations involving exact deltas are unambiguous in all cases. slay.
a second class of delta is called a semi-exact delta, and these add days (and weeks) to the delta, and treat days as a "same time next day" at all times except the two cases where the resulting date falls in the period where a daylight saving time transition is occurring. then it falls back to the 24 hour definition. so it's got a lil backup plan.
a final class of delta is an approximate delta, which includes all of the fields (years and months). this lets Date::Manip handle deltas in a way that's consistent with how most people perceive the elapsed time. and full honesty: there is some uncertainty there, because not everyone's definition of how a delta is perceived is the same β but in general, they should be closer to what most people think of. π§
β¨ TYPES OF CALCULATIONS β¨
this document describes the different types of calculations. calculations involve two types of Date::Manip objects: dates and deltas. these are described in the Date::Manip::Date and Date::Manip::Delta manuals respectively.
two objects are used (two dates, two deltas, or one of each). and in all cases, if a second object is not passed in, undef is returned. π«Ά
there are 3 types of calculations:
Date/Date calculations
a calculation involving 2 dates is used to determine the amount of time (the delta) between them.
$delta = $date1->calc($date2 [,$subtract] [,$mode]);
two dates can be worked with and a delta will be produced which is the amount of time between the two dates.
$date1 and $date2 are Date::Manip::Date objects with valid dates. the Date::Manip::Delta object returned is the amount of time between them. if $subtract is not passed in (or is 0), the delta produced is:
DELTA = DATE2 - DATE1
if $subtract is non-zero, the delta produced is:
DELTA = DATE1 - DATE2
the $subtract argument has special importance when doing approximate calculations, and this is described below in "MODE". π
if either date is invalid, a delta object will be returned which has an error associated with it.
the $mode argument describes the type of delta that is produced and is described below in "MODE".
Date/Delta calculations
date/delta calculations can be performed using either a Date::Manip::Date or Date::Manip::Delta object as the primary object:
$date2 = $date1->calc($delta [,$subtract]);
$date2 = $delta->calc($date1 [,$subtract]);
a date and delta can be combined to yield a date that is the given amount of time before or after it. β¨
$date1 and $delta are Date::Manip::Date and Date::Manip::Delta objects respectively. a new Date::Manip::Date object is produced. if either $date1 or $delta are invalid, the new date object will have an error associated with it.
both of the calls above perform the same function and produce exactly the same results. same energy, no notes.
if $subtract is not passed in, or is 0, the resulting date is formed as:
DATE2 = DATE1 + DELTA
if $subtract is non-zero, the resulting date is:
DATE2 = DATE1 - DELTA
the $subtract argument has special importance when doing approximate calculations, and this is described below in "SUBTRACTION".
Delta/Delta calculations
delta/delta calculations can be performed to add two amounts of time together, or subtract them.
$delta3 = $delta1->calc($delta2 [,$subtract] [,$no_normalize]);
if $subtract is not passed in, or is 0, the resulting delta formed is:
DELTA3 = DELTA1 + DELTA2
if $subtract is non-zero, then the resulting delta is:
DELTA3 = DELTA1 - DELTA2
$delta1 and $delta2 are valid Date::Manip::Delta objects, and a new Date::Manip::Delta object is produced.
$no_normalize can be the string 'nonormalize' or a non-zero value (in which case $subtract MUST be entered, even if it is 0). β οΈ
β¨ MODE β¨
okay so bestie, Date::Manip calculations split into two big categories: business and non-business. And inside each of those there are three lil sub-categories: exact, semi-exact, and approximate. it's giving very structured, very demure. π
πΈ Business and non-business calculations πΈ
A business calculation is one where the length of the day is determined by the length of the work day, and only business days (i.e. days in which business is conducted) count. Holidays and weekends are omitted (though there is some flexibility in defining what exactly constitutes the work week as described in the Date::Manip::Config manual). This is described in more detail below in "BUSINESS MODE CONSIDERATIONS". π’
A non-business mode calculation is the normal type of calculation where no days are ignored, and all days are full length. no skips, no holidays, just vibes. β¨
π¦ Exact, semi-exact, and approximate calculations π¦
An exact calculation is one in which the delta used (or produced) is an exact delta. An exact delta is described in more detail in the Date::Manip::Delta manual, but the short explanation is that it is a delta which only involves fields of an exactly known length (hours, minutes, and seconds). Business deltas also include days in the exact part. The value of all other fields in the delta will be zero. π―
A semi-exact calculation is one in which the deltas used (or produced) is a semi-exact delta. This is also described in the Date::Manip::Delta manual, but the short explanation is that it includes days and weeks (for standard calculations) or weeks (for business calculations) in addition to the exact fields. A semi-exact day is defined as the same clock time on two successive days. So noon to noon is 1 day (even though it may not be exactly 24 hours due to a daylight saving time transition). A week is defined as 7 days. This is described in more detail below. π
An approximate calculation is one in which the deltas used (or produced) are approximate, and may include any of the fields. no cap, it's flexible like that. π«Ά
In date-delta and delta-delta calculations, the mode of the calculation will be determined automatically by the delta. In the case of date-date calculations, the mode is supplied as an argument. π
π Mode in date-date calculations π
When doing a date-date calculation, the following call is used:
$delta = $date1->calc($date2 [,$subtract] [,$mode]);
$mode defaults to "exact". The delta produced will be be either a business or non-business delta; exact, semi-exact, or approximate, as specified by $mode.
Currently, the possible values that $mode can have are:
exact: an exact, non-business calculationsemi: a semi-exact, non-business calculationapprox: an approximate, non-business calculationbusiness: an exact, business calculationbsemi: a semi-exact, business calculationbapprox: an approximate, business calculation
π Mode in date-delta calculations π
When doing calculations of a date and a delta:
$date2 = $date1->calc($delta [,$subtract]);
$date2 = $delta->calc($date1 [,$subtract]);
the mode is not passed in. It is determined exclusively by the delta. If $delta is a business delta, A business calculation is done. If $delta is a non-business delta, a non-business calculation will be done.
The $delta will also be classified as exact, semi-exact, or approximate based on which fields are non-zero. π
π§ Mode in delta-delta calculations π§
When doing calculations with two deltas:
$delta3 = $delta1->calc($delta2 [,$subtract]);
the mode is not passed in. It is determined by the two deltas.
If both deltas are business mode, or both are non-business mode, a new delta will be produced of the same type.
It one of the deltas is a business mode and the other is not, the resulting delta will have an error condition since there is no direct correlation between the two types of deltas. Even though it would be easy to add the two together, it would be impossible to come up with a result that is meaningful. π like mixing oil and water bestie, just don't.
If both deltas are exact, semi-exact, or approximate, the resulting delta is the same. If one delta is approximate and one is not, then the resulting delta is approximate. It is NOT treated as an error. Likewise, if one is semi-exact and the other exact, a semi-exact delta is produced.
π TIMEZONE CONSIDERATIONS π
π date-date calculations π
When doing a business calculation, both dates must be in the same time zone or an error is produced. π¨
For non-business calculations, when calculating the difference between two dates in different time zones, $date2 will be converted to the same timezone as $date1 and the returned date will be in this timezone. βοΈ
π date-delta calculations π
When adding a delta to a date, the resulting date will be in the same time zone as the original date.
π delta-delta calculations π
No timezone information applies.
It should also be noted that daylight saving time considerations are currently ignored when doing business calculations. In common usage, daylight saving time changes occurs outside of the business day, so the business day length is constant. As a result, daylight saving time is ignored. β° (she said "not my problem")
π BUSINESS MODE CONSIDERATIONS π
In order to correctly do business mode calculations, a config file should exist which contains the section defining holidays (otherwise, weekends will be ignored, but all other days will be counted as business days). This is documented below, and in the Date::Manip::Config section of the documentation. Some config variables (namely WorkWeekBeg, WorkWeekEnd, WorkDayBeg, WorkDayEnd, and WorkDay24Hr) defined the length of the work week and work day.
If the workday is defined as 08:00 to 18:00, a work week consisting of Mon-Sat, and the standard (American) holidays, then from Tuesday at 12:00 to the following Monday at 14:00 is 5 days and 2 hours. If the "end" of the day is reached in a calculation, it automatically switches to the next day. So, Tuesday at 12:00 plus 6 hours is Wednesday at 08:00 (provided Wed is not a holiday). Also, a date that is not during a workday automatically becomes the start of the next workday. So, Sunday 12:00 and Monday at 03:00 both automatically becomes Monday at 08:00 (provided Monday is not a holiday). ποΈ
Note that a business week is treated the same as an exact week (i.e. from Tuesday to Tuesday, regardless of holidays). Because this means that the relationship between days and weeks is NOT unambiguous, when a semi-exact delta is produced from two dates, it will be in terms of d/h/mn/s (i.e. no week field). π
Anyone using business mode is going to notice a few quirks about it which should be explained. When I designed business mode, I had in mind what a business which promises 1 business day turnaround really means. π§
If you do a business calculation (with the workday set to 9:00-17:00), you will get the following:
Saturday at noon + 1 business day = Tuesday at 9:00
Saturday at noon - 1 business day = Friday at 9:00
What does this mean? π€
As an example, say I use a business that works 9-5 and they have a drop box so I can drop things off over the weekend and they promise 1 business day turnaround. If I drop something off Friday night, Saturday, or Sunday, it doesn't matter. They're going to get started on it Monday morning. It'll be 1 business day to finish the job, so the earliest I can expect it to be done is around 17:00 Monday or 9:00 Tuesday morning. Unfortunately, there is some ambiguity as to what day 17:00 really falls on, similar to the ambiguity that occurs when you ask what day midnight falls on. Although it's not the only answer, Date::Manip treats midnight as the beginning of a day rather than the end of one. In the same way, 17:00 is equivalent to 9:00 the next day and any time the date calculations encounter 17:00, it automatically switch to 9:00 the next day. Although this introduces some quirks, I think this is justified. I also think that it is the way most people think of it. If I drop something off first thing Monday morning, I would expect to pick it up first thing Tuesday if there is 1 business day turnaround. π«‘
Equivalently, if I want a job to be finished on Saturday (despite the fact that I cannot pick it up since the business is closed), I have to drop it off no later than Friday at 9:00. That gives them a full business day to finish it off. Of course, I could just as easily drop it off at 17:00 Thursday, or any time between then and 9:00 Friday. Again, it's a matter of treating 17:00 as ambiguous. π
So Saturday + 1 business day = Tuesday at 9:00 (which means anything from Monday 17:00 to Tuesday 9:00), but Monday at 9:01 + 1 business day = Tuesday at 9:01 which is unambiguous. β¨
It should be noted that when adding years, months, and weeks, the business day is ignored. Once they've been added, the resulting date is forced to be a business time (i.e. it moves to the start of the next business day if it wasn't one already) before proceeding with the days, hours, minutes, and seconds part. π―
β¨ EXACT, SEMI-EXACT, AND APPROXIMATE DATE/DELTA CALCULATIONS β¨
okay bestie, this section is where we get into the actual mechanics of how exact, semi-exact, and approximate calculations go down for date/delta math. grab a snack, we're going in π
so first thing: every single calculation leans on some quantities that are rock solid, no notes:
1 year = 12 months
1 week = 7 days
1 hour = 60 minutes
1 minute = 60 seconds
but then there are two relationships that are NOT exact, and they're the whole drama of this page:
1 month = ? days
1 day = ? hours
for non-business calculations, a day is usually 24 hours long. but DST transitions can make a day be 23 or 25 hours long (or, like, some other length entirely, because timezones are chaotic π), so that relation is simply not exact. whenever it's possible, a day is measured as the same time on two days (Tuesday at noon β Wednesday at noon), even if that stretch isn't precisely 24 hours. for business calculations though, the length of a day is decided by the length of the work day, so it's known exactly. no ambiguity, we love that for us.
Exact calculations only ever touch quantities of time with a known length, so there's zero ambiguity in them. periodt.
Approximate and semi-exact calculations do involve variable length fields though, so they need special treatment.
to do an approximate or semi-exact calculation, the delta gets added to a date in pieces, where each piece's fields have an exact, known relationship.
for a non-business calculation, it happens in these steps:
year/month fields added
week/day fields added
hour/minute/second fields added
for a business calculation, the steps are:
year/month fields added
week field added
day field added
hour/minute/second fields added
after every step, a valid date has to exist, or it gets adjusted before we move on to the next step. but heads up: for business calculations, the first step has to produce a valid date, but not necessarily a business date. the second step is the one that produces a valid business date. iykyk.
a whole series of examples is about to make this make sense.
π A date and non-business approximate delta
date = Mar 31 2001 at 12:00:00
delta = 1 year, 1 month, 1 day, 1 hour
first, the year/month fields get added without touching any other field. that would produce:
Apr 31, 2002 at 12:00
which is, um, not valid π any time the year/month fields produce a day past the end of the month, the result gets 'truncated' to the last day of the month, so we actually get:
Apr 30, 2002 at 12:00
next the week/day fields are added, producing:
May 1, 2002 at 12:00
and finally the exact fields (hour/minute/second) get added, producing:
May 1, 2002 at 13:00
slay. that's the whole pipeline. π₯
π¦ A simple business calculation
assuming a normal Monday-Friday work week from 8:00 - 17:00:
date = Wed, Nov 23, 2011 at 12:00
delta = 1 week, 1 day, 1 hour
first, the week field is added:
Wed, Nov 30, 2011 at 12:00
then the day field is added:
Thu, Dec 1, 2011 at 12:00
then the exact fields are added:
Thu, Dec 1, 2011 at 13:00
πΈ A business example where a holiday impacts it
in America, Jul 4 is a holiday, so Mon, Jul 4, 2011 is not a work day. rude of it, honestly.
date = Mon, Jun 27, 2011 at 12:00
delta = 1 week, 1 day, 1 hour
first, the week field is added:
Mon, Jul 4, 2011 at 12:00
since that's not a work day, it immediately becomes:
Tue, Jul 5, 2011 at 8:00
then the day field is added:
Wed, Jul 6, 2011 at 8:00
and finally the remaining fields:
Wed, Jul 6, 2011 at 9:00
see how the holiday just... shifted the whole vibe? π iconic behavior from the calendar.
π Calculation where daylight savings time impacts it (fall example)
in the America/New_York timezone (Eastern time), on November 6, 2011, this time change went down:
2011-11-06 02:00 EDT => 2011-11-06 01:00 EST
three simple calculations show how it's handled:
date = 2011-11-05 02:30 EDT
delta = 1 day
adding the day produces:
2011-11-06 02:30 EDT
which is valid, so that's the result. easy.
similarly:
date = 2011-11-07 02:30 EST
delta = -1 day
produces:
2011-11-06 02:30 EST
which is valid.
finally:
date = 2011-11-05 02:30 EDT
delta = 2 days
produces:
2011-11-07 02:30 EST
the calculation will preserve the savings time where possible, so the resulting day has the same offset from UTC. if that's not possible, but the resulting day is valid in the other offset, that one gets used instead. flexible queen behavior. π
β Calculation where daylight savings time impacts it (spring example)
in the America/New_York timezone (Eastern time), on March 13, this time change went down:
2011-03-13 02:00 EST => 2011-03-13 03:00 EDT
in this case, a calculation may produce an invalid date. π
date = 2011-03-12 02:30 EST
delta = 1 day
produces:
2011-03-13 02:30 EST
which is not valid. and neither is:
2011-03-13 02:30 EDT
so in this case, the calculation gets redone, converting days to 24-hour periods, meaning the calculation becomes:
date = 2011-03-12 02:30 EST
delta = 24 hours
which produces a valid date:
2011-03-13 03:30 EDT
and that's the save. no cap. π«Ά
π EXACT, SEMI-EXACT, AND APPROXIMATE DATE/DATE CALCULATIONS π
now for the other direction: date/date calculations. this section has the deets on exactly how exact, semi-exact, and approximate calculations are performed when you're finding the delta between two dates.
when you calculate the delta between two dates, the delta can take different forms depending on the mode passed in. an exact calculation produces a delta that includes only exact fields. a semi-exact calculation may produce a semi-exact delta, and an approximate calculation may produce an approximate delta. important note tho: if the two dates are close enough together, an exact delta will be produced (even if the mode is semi-exact or approximate), or it may produce a semi-exact delta in approximate mode.
for example, the two dates "Mar 12 1995 12:00" and "Apr 13 1995 12:00" would have an exact delta of "744 hours", and a semi-exact delta of "31 days". and they'd have an approximate delta of "1 month 1 day".
two dates, "Mar 31 12:00" and "Apr 30 12:00", would have deltas of "720 hours" (exact), "30 days" (semi-exact) or "1 month" (approximate).
approximate mode is a more human way of looking at things (like, you'd say 1 month and 2 days way more often than 33 days, bestie), but it's less meaningful in terms of absolute time. it's giving vibes over precision.
one thing to remember: an exact delta is exactly the amount of time that has passed, including all effects of daylight saving time. semi-exact and approximate deltas usually ignore the affects of daylight saving time. yes, that's a real trade-off, not a typo.
π SUBTRACTION π
in exact and semi-exact calculations, and in delta-delta calculations, the $subtract argument is easy to understand. easy peasy.
when working with an approximate delta though (either when adding an approximate delta to a date, or when taking two dates to get an approximate delta), there's a degree of uncertainty in how the calculation is done, and $subtract is the argument used to specify exactly how the approximate delta is to be use. an example illustrates this quite well:
if you take the date Jan 4, 2000 and subtract a delta of "1 month 1 week" from it, you end up with Nov 27, 1999 (Jan 4, 2000 minus 1 month is Dec 4, 1999; minus 1 week is Nov 27, 1999). but Nov 27, 1999 plus a delta of "1 month 1 week" is Jan 3, 2000 (Nov 27, 1999 plus 1 month is Dec 27, 1999; plus 1 week is Jan 3, 2000).
in other words, the approximate delta (but NOT the exact or semi-exact delta) is different depending on whether you move from the earlier date to the later date, or vice versa. and depending on what you're calculating, both are useful.
to resolve this, $subtract can take on the values 0, 1, or 2, and each one means something different.
π§ $subtract in approximate date-date calculations
in the call:
$delta = $date1->calc($date2,$subtract,"approx");
if $subtract is 0, the resulting delta can be added to $date1 to get $date2. obviously $delta may still be negative (if $date2 comes before $date1). that's allowed, no judgment.
if $subtract is 1, the resulting delta can be subtracted from $date1 to get $date2 (the deltas from these two are identical except for having an opposite sign).
if $subtract is 2, the resulting delta can be added to $date2 to get $date1. in other words, these two are identical:
$delta = $date1->calc($date2,2,"approx");
$delta = $date2->calc($date1,"approx");
same thing, two ways to write it. cute. π
π $subtract in approximate date-delta calculations
in the call:
$date2 = $date1->calc($delta,$subtract);
if $subtract is 0, the resulting date is determined by adding $delta to $date1.
if $subtract is 1, the resulting date is determined by subtracting $delta from $date1.
if $subtract is 2, the resulting date is the date which $delta can be added to to get $date1.
for business mode calculations, $date1 will first be adjusted to be a valid work day (if it isn't already), so this may lead to non-intuitive results. don't say we didn't warn you.
and in some cases, it's literally impossible to do a calculation with$subtract = 2. as an example, if the date is"Dec 31"and the delta is"1 month", there is no date which you can add"1 month"to to get"Dec 31". when this occurs, the date returned has an error flag. π so check that flag, bestie, fr fr.
π APPROXIMATE DATE/DATE CALCULATION π
okay bestie, so when we're looking at the approximate delta between two dates, there are literally two different ways to look at it. two!! and they give you different answers, which is a lil wild but honestly iconic. β¨
the 5.xx era πΈ
back in Date::Manip 5.xx, the approximate delta between these two dates:
Jan 10 1996 noon
Jan 7 1998 noon
was 1:11:4:0:0:0:0 (or 1 year, 11 months, 4 weeks). the way this got calculated? the first date was adjusted as far as it could go towards the second date without going past it, one unit at a time, starting with the years and ending with the seconds.
this gave a strictly positive or negative delta, which sounds clean ngl, but it isn't actually how most people would think of the delta. π
the 6.0 glow-up π
as of Date::Manip 6.0, the delta is 2:0:0:-3:0:0:0 (or 2 years minus 3 days). and yeah, that leads to mixed-sign deltas β messy? maybe. but it is actually how more people would think about the delta. plus it has the additional advantage of being easier to calculate. we love a practical queen. π
the deets for each mode π
for non-business mode calculations, the year/month part of the approximate delta will move a date from the year/month of the first date into the year/month of the second date. the remainder of the delta will adjust the days/hours/minutes/seconds as appropriate.
for approximate business mode calculations, the year, date, and week parts will be done approximately, and the remainder will be done exactly.
π¦ KNOWN BUGS π¦
None known. β¨ (we love a bug-free era, periodt)
π BUGS AND QUESTIONS π
Please refer to the Date::Manip::Problems documentation for information on submitting bug reports or questions to the author. π«Ά
β SEE ALSO β
Date::Manipβ main module documentation
π LICENSE π
This script is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
π AUTHOR π
Sullivan Beck (https://github.com/SBECK-github/)
and that's a wrap bestie!! this page was brought to you by perl v5.42.3, dated 2026-09-01, and it's the Date::Manip::Calc(3) manpage π go forth and calculate, you absolute main character π«Άβ¨
π¦ where this page comes from
- fedora 43: perl-Date-Manip 7.00-1.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- fedora 44: perl-Date-Manip 7.00-1.fc44 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms