mysql.h


DATE_ADD(), DATE_SUB()

DATE_ADD(date,INTERVAL expr type) 
DATE_SUB(date,INTERVAL expr type)

Estas funciones realizan aritmética con fechas. Desde MySQL 3.23, INTERVAL expr type se permite en cualquiera de los lados del operador + si la expresión en el otro lado es un valor de tipo date o datetime. Para el operador -, INTERVAL expr type se permite sólo en el lado derecho, porque no tiene sentido restar un valor de tipo date o datetime desde un intervalo. (Ver ejemplos.) date es un valor de tipo DATETIME o DATE que especifica la fecha de comienzo. expr es una expresión que especifica un valor de intervalo a añadir o restar desde la fecha de comienzo. expr es una cadena; puede empezar con un '-' para intervalos negativos. type es una palabra clave que indica cómo debe interpretarse la expresión. La tabla siguiente muestra cómo se relacionan los argumentos type y expr:

Valor type Formato de expr esperado
MICROSECOND MICROSECONDS
SECOND SECONDS
MINUTE MINUTES
HOUR HOURS
DAY DAYS
WEEK WEEKS
MONTH MONTHS
QUARTER QUARTERS
YEAR YEARS
SECOND_MICROSECOND 'SECONDS.MICROSECONDS'
MINUTE_MICROSECOND 'MINUTES.MICROSECONDS'
MINUTE_SECOND 'MINUTES:SECONDS'
HOUR_MICROSECOND 'HOURS.MICROSECONDS'
HOUR_SECOND 'HOURS:MINUTES:SECONDS'
HOUR_MINUTE 'HOURS:MINUTES'
DAY_MICROSECOND 'DAYS.MICROSECONDS'
DAY_SECOND 'DAYS HOURS:MINUTES:SECONDS'
DAY_MINUTE 'DAYS HOURS:MINUTES'
DAY_HOUR 'DAYS HOURS'
YEAR_MONTH 'YEARS-MONTHS'

Los valores de tipo DAY_MICROSECOND, HOUR_MICROSECOND, MINUTE_MICROSECOND, SECOND_MICROSECOND, and MICROSECOND están permitidos desde MySQL 4.1.1. Los valores QUARTER y WEEK están permitidos desd MySQL 5.0.0. MySQL permite cualquier delimitador de puntuación en el formato de expr. Los mostrados en la tabla son los delimitadores propuestos. Si el argumento date es un valor DATE y los cáculos involucran sólo las partes de YEAR, MONTH y DAY (es decir, no las partes de hora), el resultado es un valor DATE. En otro caso, el resultado en un valor DATETIME:

mysql> SELECT '1997-12-31 23:59:59' + INTERVAL 1 SECOND;
+-------------------------------------------+
| '1997-12-31 23:59:59' + INTERVAL 1 SECOND |
+-------------------------------------------+
| 1998-01-01 00:00:00                       |
+-------------------------------------------+
1 row in set (0.02 sec)

mysql> SELECT INTERVAL 1 DAY + '1997-12-31';
+-------------------------------+
| INTERVAL 1 DAY + '1997-12-31' |
+-------------------------------+
| 1998-01-01                    |
+-------------------------------+
1 row in set (0.00 sec)

mysql> SELECT '1998-01-01' - INTERVAL 1 SECOND;
+----------------------------------+
| '1998-01-01' - INTERVAL 1 SECOND |
+----------------------------------+
| 1997-12-31 23:59:59              |
+----------------------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE_ADD('1997-12-31 23:59:59',
    -> INTERVAL 1 SECOND);
+----------------------------------------------------+
| DATE_ADD('1997-12-31 23:59:59', INTERVAL 1 SECOND) |
+----------------------------------------------------+
| 1998-01-01 00:00:00                                |
+----------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE_ADD('1997-12-31 23:59:59',
    -> INTERVAL 1 DAY);
+-------------------------------------------------+
| DATE_ADD('1997-12-31 23:59:59', INTERVAL 1 DAY) |
+-------------------------------------------------+
| 1998-01-01 23:59:59                             |
+-------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE_ADD('1997-12-31 23:59:59',
    -> INTERVAL '1:1' MINUTE_SECOND);
+---------------------------------------------------------------+
| DATE_ADD('1997-12-31 23:59:59', INTERVAL '1:1' MINUTE_SECOND) |
+---------------------------------------------------------------+
| 1998-01-01 00:01:00                                           |
+---------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE_SUB('1998-01-01 00:00:00',
    -> INTERVAL '1 1:1:1' DAY_SECOND);
+----------------------------------------------------------------+
| DATE_SUB('1998-01-01 00:00:00', INTERVAL '1 1:1:1' DAY_SECOND) |
+----------------------------------------------------------------+
| 1997-12-30 22:58:59                                            |
+----------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE_ADD('1998-01-01 00:00:00',
    -> INTERVAL '-1 10' DAY_HOUR);
+------------------------------------------------------------+
| DATE_ADD('1998-01-01 00:00:00', INTERVAL '-1 10' DAY_HOUR) |
+------------------------------------------------------------+
| 1997-12-30 14:00:00                                        |
+------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
+-----------------------------------------+
| DATE_SUB('1998-01-02', INTERVAL 31 DAY) |
+-----------------------------------------+
| 1997-12-02                              |
+-----------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT DATE_ADD('1992-12-31 23:59:59.000002',
    ->                 INTERVAL '1.999999' SECOND_MICROSECOND);
        -> '1993-01-01 00:00:01.000001'

Si se especifica un valor de intervalo demasiado corto (que no incluye todas las partes del intervalo que se esperan dada la palabra clace en tipo), MySQL asume que se han perdido las partes de la izquierda del valor de intervalo. Por ejemplo, si se especifica un tipo DAY_SECOND, se espera que el valor de expr contenga las partes correspondientes a días, horas, minutos y segundos. Si se especifica un valor como '1:10', MySQL asume que las partes de días y horas se han perdido y el valor representa minutos y segundos. En otras palabras, '1:10' DAY_SECOND se interpreta del mismo modo que si se hubiese usado '1:10' MINUTE_SECOND. Esto es análogo al modo en que MySQL interpreta valores TIME que representan intervalos de tiempo en lugar de tiempo con respecto al día. Si se suma o resta desde un valor de fecha algo que contiene la parte de la hora, el resultado se convierte automáticamente a un valor de fecha y hora:

mysql> SELECT DATE_ADD('1999-01-01', INTERVAL 1 DAY);
        -> '1999-01-02'
mysql> SELECT DATE_ADD('1999-01-01', INTERVAL 1 HOUR);
        -> '1999-01-01 01:00:00'

Se se usan fechas mal formadas, el resultado es NULL. Si se suma MONTH, YEAR_MONTH o YEAR y la fecha resultado contiene un día que es mayor que el máximo para el nuevo mes, el día se ajusta al máximo para el mes nuevo:

mysql> SELECT DATE_ADD('1998-01-30', interval 1 month);
        -> '1998-02-28'

Notar que para el ejemplo anterior la palabra clave INTERVAL y el especificador de tipo no son case-sensitive.