NAME
DatetimePlus — Find the datetime that comes some time after the given one.
SYNOPSIS
DatetimePlus DatetimeVariable TimeAmount
DESCRIPTION
Return Value
Datetime got by adding some time amount to given datetime.
Arguments
DatetimeVariableDatetime to add to.
TimeAmountHow much to add. See More Info and Examples for format.
More Info
The format of the TimeAmount argument is "xY xM xW xD xH xM xS" where each x is an integer (can be negative, but no decimals) and the components represent years, months, weeks, days, hours, minutes, and seconds. Currently, it is not possible to change this format and each of the components must be included. But perhaps in a future release we may support something like "1 year 7 days" or the like.

The rest can be summarized as follows: it works pretty much the same as OO Calc, which is based on Excel, but in various scenarios what you get back may not be what you would have expected. So we will go over how it works and specific cases where what you get back may seem odd.

If you add one month to a date then the month will increase by one, so long as the day is the 28th or earlier. If the date you add to starts on the 1st and you add one month then you will get back a date that is on the 1st of the next month, 2nd goes to the 2nd, 3rd to the 3rd, and so on. The exception is when the month it would be going to does not have the day you are adding from. In that case, it will go into the next month. So if you are at the 31st, and add one month, and the next month has only 30 days then it will go to the 1st of the next month. For example, DatetimePlus {2000-03-31 00:00:00} {0Y 1M 0W 0D 0H 0M 0S} returns 2000-05-01 00:00:00 because April has only 30 days.

But suppose you call DatetimePlus {2000-03-31 00:00:00} {0Y 1M 0W 1D 0H 0M 0S}? Will it first add the day and go to April 1st, and then go to May 1st? No, what actually happens is that the months and years are added first and then clock scan is called to convert that datetime into to seconds (since start of epoch), then the rest of the components are added. clock scan accepts "invalid" dates like 2000-04-31 and will convert that to the same number of seconds as 2000-05-01.

It may well be that, say, adding one month 12 times gives you a different result than adding 12 months one time. (Of course, it is also possible to avoid using months or years if you do not think they will work and use some number of days instead).

But still, overall, this way is good in that you can schedule something to happen on the 1st of the month and then use this to get the 1st of the next month, etc. It is only in cases of days after the 28th that it may not work.

Likewise, for the years it will first add to the year component of the date before converting to seconds. This means if you add one year to February 29th (a leap year) then you will get back March 1st, but if you instead add four years, then you will get back February 29th again.

Note that in various instances you could add a month and then subtract it or add a year and then subtract it and you will not get back to the start. For instance, if you add a year to February 29th, 2000 then you get back March 1st, 2001. If you then subtract a year, you get back March 1st, 2000. There is no way for the code to know you wanted to have February 29, 2000 (certainly not without complications). So this command is not intended for use in those scenarios. But, again, this is consistent with OO Calc and Excel (most likely).

As far as daylight savings goes, it handles it the same as clock scan / clock format do. So it may well be that you add some number of months to a datetime and find that it has also changed by an hour due to daylight savings.

For serious and critical applications for this command, it is recommended you review the source code, the tests, and the examples to get a strong feeling for exactly how it behaves.

Most likely the behavior of this command will remain simple in future releases. If you want complex datetime handling, you might use this simple command to get going, figure out what you want, and then find or make your own functionality to give you the complexities you need.

Note that this command uses IsDatetime to validate the input date. That command is, in turn, (currently) only as good as clock scan. So if clock scan allows an invalid date, then this will as well.

Finally, note that you may simply want to use a combination of clock scan, expr, and clock format to get the behavior you want. This command was created to be able to support, for instance, scheduling things on the same day each month, regardless of how many days there are in the month.


For information regarding exceptions / errors, see here.
EXAMPLES
% DatetimePlus {2000-01-02 03:04:05} {1Y 1M 1W 1D 1H 1M 1S}

2001-02-10 04:05:06
% set MyVar {2000-01-02 03:04:05}
2000-01-02 03:04:05
% DatetimePlus @MyVar {1Y 1M 1W 1D 1H 1M 1S}
2001-02-10 04:05:06
% puts $MyVar
2001-02-10 04:05:06
SEE ALSO
DateMinus, DatePlus, DatetimeMinus
KEYWORDS
arithmetic, date, datetime, math, time