This error is correct, there is no Feb 29, 2013.
It could return March 1, 2013... but then adding a year to Feb 29, 2012 and
adding a year and a day give the same result which doesn't make sense.
It does present a problem... how do you reliably say "same date next year"?
This is very similar to the 'end_of_month_mode' feature in
DateTime::Duration, which handles how (for example) "Jan 30 + 1 month"
calculations are handled. Therefore, I would suggest a configuration
option for handling how wrapping is done involving leap years.
For that matter, leap seconds pose the same problem - if 00:00:60 is a
leap second, how does one handle 00:00:60 + 1 minute? is it wrapped to the
next minute (00:02:00), truncated (00:01:59), or...?
I'd hoped I could stay out of this, but maybe the following thought will
helpful.
It seems that the root of the difficulty is an exclusivity that there
can only be one date representing each day. The canonical date. Calling
February 1 by the name January 32 is "wrong" and if you don't stop it,
they won't let you enter third grade, or something. Silly authoritatians.
If months are day offsets into the year, and day-of-month is the
additional days to add to the offset, and this approach is applied to
smaller levels too, all the screwey questions can fall into place. A
year after 29 feb is 1 mar of the following year. A month after August
31 is October 1, and two months after August 31 is October 31. Also
known, but certainly not canonically, as February
something-hundred-something. October 31 is also March 245 in any year.
Do any existing systems work that way? SQLite appears to, except for the
input range issues -- no DOM past 31 and no seconds past 59
sqlite> select strftime('%Y-%m-%d %H:%M:%S', '2013-02-31T00:01:59');
2013-03-03 00:01:59
sqlite> select strftime('%Y-%m-%d %H:%M:%S', '2013-02-32T00:01:59');
sqlite> select date( '2013-08-31');
2013-08-31
sqlite> select date( '2013-08-31', "1 months");
2013-10-01
sqlite> select date( '2013-08-31', "2 months");
2013-10-31
Following the same approach, 00:00:60 + 1 minute becomes 00:01:60
which would canonicalize to 00:02:01, but leap seconds really have no
business leaking out of the clock, in my opinion. I'd rather see time
formally declared in terms of Earth's rotations outside of astronomy and
physics.