DateMinus — Find the date that comes some time before the given one.
DateMinus DateVariable TimeAmount
Return Value
Date got by adding some amount of time to given date.
DateVariableDate to add to.
TimeAmountHow much to add. See More Info and Examples for format.
More Info
This command will multiply each component by -1 and then call DatePlus.

The format of the TimeAmount argument is "xY xM xW xD" 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 so 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 subtract one month from a date, then the month will go down by one, so long as the day is the 28th or earlier. If the date you subtract from starts on the 1st and you subtract one month then you will get back a date that is on the 1st of the previous month. The exception is when the month it would be going to does not have the day you are subtracting from. In that case, it will go forward again, over into the next month. So if you are at the 31st, and subtract one month, and the next month has only 30 days (no 31st) then it will go back to the 1st of the current month. For example, DateMinus {2000-05-31 00:00:00} {0Y 1M 0W 0D 0H 0M 0S} returns 2000-05-01 00:00:00 because we would have had April 31st, but April has only 30 days, and so we take that extra day and go forward again to May 1st.

But suppose you call DateMinus {2000-06-01 00:00:00} {0Y 1M 0W 1D 0H 0M 0S}? Will it first subtract the day and go to May 31st, and then go to May 1st as before? No, you will get back April 30th. What actually happens is that the months and years are subtracted 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 subtracted.

It may well be that, say, subtracting one month 12 times gives you a different result than subtracting 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).

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

Note that in various instances you could subtract a month and then add it back or subtract a year and then add it back but you will not get back to the start. For instance, if you subtract a year from February 29th, 2000 then you get back March 1st, 1999. If you then add a year, you get back March 1st, 2000. There is no way for the code to know if 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).

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 date 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 IsDate 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 support, for instance, scheduling things on the same day each month, regardless of how many days are in the month.

For information regarding exceptions / errors, see
% DateMinus {2001-02-10} {1Y 1M 1W 1D}
% set MyVar {2001-02-10}
% DateMinus @MyVar {1Y 1M 1W 1D}
% puts $MyVar
DatePlus, DatetimeMinus
arithmetic, date, math