Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I've writing a date-time library, and need to implement the addition of a duration to a date-time.

If I add a 1 month duration: P1M to the 31st March 2012: 2012-03-31, does the standard define what the result is?

Because the resulting date (31st April) does not exist, there are at least two options:

  • Fall back to the last day of the resulting month. This is the approach currently taken by the ThreeTen API, the (alpha) reference implementation of JSR-310:
ZonedDateTime date = ZonedDateTime.parse("2012-03-31T00:00:00Z");
Period duration = Period.parse("P1M");
System.out.println(date.plus(duration).toString());

// 2012-04-30T00:00Z
  • Carry the extra day to the next month. This is the approach taken by the DateTime class in PHP:
$date = new DateTime('2012-03-31T00:00:00Z');
$duration = new DateInterval('P1M');
echo $date->add($duration)->format('c');

// 2012-05-01T00:00:00+00:00

I'm surprised that two date-time libraries contradict on this point, so I'm wondering whether the standard defines the result of this operation?

share|improve this question
4  
Counting with dates can introduce remarkable behaviour: March 31st + 2 months can be May 31st while ((March 31st)+ 1 month) + 1 month) can be either may 30th or June 1st but never May 31st –  Pieter B Dec 19 '12 at 12:49
1  
You can even land on a time that never happened (The hour you leap ahead for daylight savings) –  brian Dec 19 '12 at 14:23

3 Answers 3

I work in financial domain, and I understand there are different conventions to follow these corner cases.

Follow Wikipedia article Day Count Convention for details.

ISO_8601 does not have any specific value for month as duration, but the link The Mathematics of the ISO 8601 Calendar suggest month as 30.6, year as 365.25, with additional handling for leap years.

share|improve this answer

That's an edge case. I got no specifications to back my statement up, but...

You should use the last date of the next month. Else you have added two months and not one month.

share|improve this answer

Adding by months makes no sense. You should only add by days or fractions of days. Even years can be problematic when dealing with leap days. Did you mean one year or 365 days or 366 days?

You should establish relative addition. Are you looking for end of the month, first of the month, or last workday of the month?

For end of month I use: To calculate the last day of April

  1. increment month by one unit beyond the month, adjusting the year as necessary;
  2. change day of month to one;
  3. Then subtract one day unit;
share|improve this answer
2  
So it should be illegal to represent the problem domain concept "on the same day next month" in code? Or only inconvenient? –  Useless Dec 19 '12 at 14:07
1  
Actually, even adding days isn't always clear. Does adding "a day" to 11:30pm on the Saturday before time springs forward advance 24 hours (to 12:30am Monday) or 23 hours (to 11:30pm Sunday)? –  supercat Jul 26 at 0:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.