Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Standards for Date/Time addition?

I'm looking for standards for Date/Time addition. I haven't been able to find any. In particular I'm hoping to find a spec that defines what should happen when you add a month to a date like January 31st. Is the right answer February 28th(/29th)? March 1st? March 2nd?

I've seen inconsistent implementations between different tools (PHP & MySQL in this case), and I'm trying to find some sort of standards to base my work on.

Differing Results:

PHP

$end = strtotime("+1 month", 1314835200);
//1317513600   Sat, 01 Oct 2011 20:00:00 -0400

MySQL

SELECT UNIX_TIMESTAMP(DATE_ADD(FROM_UNIXTIME(1314835200), INTERVAL 1 MONTH));
#1317427200    Fri, 30 Sep 2011 20:00:00 -0400

Oracle

SELECT ADD_MONTHS('31-Aug-11', 1) FROM dual;
#30-SEP-11

(sorry for the format change, my oracle foo is weak)

Java

Calendar c = Calendar.getInstance();
c.clear();
c.set( 2011, Calendar.AUGUST, 31 );
c.add( Calendar.MONTH, 1 );
c.getTime()
#Fri Sep 30 00:00:00 EDT 2011
like image 899
preinheimer Avatar asked Sep 30 '11 18:09

preinheimer


People also ask

What is the standard timestamp format?

The default format of the timestamp contained in the string is yyyy-mm-dd hh:mm:ss.

What is the international date format?

The international format yyyy-mm-dd or yyyymmdd is also accepted, though this format is not commonly used. The formats d. 'month name' yyyy and in handwriting d/m-yy or d/m yyyy are also acceptable.)

Can you subtract timestamps?

You can subtract a date from a date, or a time from a time. You cannot subtract a timestamp from a timestamp. If a date/time value is the operand of an addition, the other operand must be a duration. Subtracting two date/time values is different from subtracting a duration from a date/time value.


2 Answers

According to the POSIX.1-2001 standard, next month (as in incrementing tm_mon before calling mktime) is done by adjusting the values until they fit. So, for example, next month from January 31, 2001 is March 3, 2001. This is because the tm_mday of 31 isn't valid with tm_mon of 1 (February), so it is normalized to tm_mon of 2 (March) and tm_mday of 3.

The next month from January 31, 2000 is March 2, 2000, because Feb. has 29 days that year. The next month from January, 1 2038 doesn't exist, depending.

The great thing about standards is there are so many to chose from. Check the SQL standard, I bet you can find a different meaning of next month. I suspect ISO 8601 may give you yet another choice. Point is, there are many different behaviors, the meaning of 'next month' is very domain-specific.

edit: I think I've found how SQL-92 handles it, apparently asking for next month from January 31 is an error.

Links:

  • SQL-92: http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt
  • POSIX: http://pubs.opengroup.org/onlinepubs/9699919799/ (though apparently that version now defers to ISO C, which doesn't seem as clear. The mktime manpage on my machine is clear, though)
  • ISO C: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
  • Java: http://download.oracle.com/javase/6/docs/api/java/util/Calendar.html
like image 112
derobert Avatar answered Oct 11 '22 06:10

derobert


I believe the defacto standard is ISO 8601. Unfortunately, there are many ambiguities, for example:

Date arithmetic is not defined

2001-03-30 + P1M = 2001-04-29 (Add 30 days)
2001-03-30 + P1M = 2001-04-30 (Add 1 mon.)

Addition is not commutative or associative

2001-03-30 + P1D + P1M = 2001-04-30
2001-03-30 + P1M + P1D = 2001-05-01

Subtraction is not the inverse of Addition.

Precision of decimal fractions can vary.

The full specification can be found at http://www.iso.org/iso/catalogue_detail.htm?csnumber=26780

I think each product is attempting to adhere to an impossible to implement standard. The ambiguous parts are open to interpretation and so everyone interprets. This is the same standard that opened us up to the Y2K bug!!

Myself, I favor an implementation that converts a date/time to a 1970 based number (UNIX timestamp), performs the calculation and converts back. I believe this is the approach taken by Oracle/MySQL. I am surprised that more attention has not been paid this issue, as it is really important, sometimes critical, in so many applications. Thanks for the question!

Edit: While doing some more reading, I found Joe Celko's thoughts on different date/time representations and standardization HERE.

like image 37
2 revs Avatar answered Oct 11 '22 07:10

2 revs