Ajouter un intervalle à une donnée temporelle

      Avec Oracle Database, il est courant de voir des syntaxes du style sysdate + 1 ou current_timestamp + 1/2 pour ajouter un intervalle à une donnée temporelle. Que signifient ces syntaxes ?
      Démonstration avec Oracle Database 11.2.0.2 :

Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production SQL> select to_char(current_date,'DD/MM/YY HH24:MI') as hui, to_char(current_date + 1/1440,'DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(current_date+1, 'DD/MM/YY HH24:MI') as demain from dual; HUI UNE_MINUTE_PLUS DEMAIN -------------- --------------- -------------- 18/12/16 11:54 18/12/16 11:55 19/12/16 11:54 SQL> select to_char(current_timestamp,'DD/MM/YY HH24:MI') as hui, to_char(current_timestamp + 1/1440,'DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(current_timestamp+1, 'DD/MM/YY HH24:MI') as demain from dual; HUI UNE_MINUTE_PLUS DEMAIN -------------- --------------- -------------- 18/12/16 13:50 18/12/16 13:51 19/12/16 13:50 SQL> select to_char(current_timestamp,'DD/MM/YY HH24:MI') as hui, to_char(current_timestamp + 1/1440,'DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(current_timestamp+1, 'DD/MM/YY HH24:MI') as demain from dual; HUI UNE_MINUTE_PLUS DEMAIN -------------- --------------- -------------- 18/12/16 13:50 18/12/16 13:51 19/12/16 13:50 SQL> select to_char(sysdate,'DD/MM/YY HH24:MI') as hui, to_char(sysdate + 1/1440,'DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(sysdate+1, 'DD/MM/YY HH24:MI') as demain from dual; HUI UNE_MINUTE_PLUS DEMAIN -------------- --------------- -------------- 18/12/16 13:51 18/12/16 13:52 19/12/16 13:51 SQL> select to_char(systimestamp,'DD/MM/YY HH24:MI') as hui, to_char(systimestamp + 1/1440,'DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(systimestamp+1, 'DD/MM/YY HH24:MI') as demain from dual; HUI UNE_MINUTE_PLUS DEMAIN -------------- --------------- -------------- 18/12/16 13:51 18/12/16 13:52 19/12/16 13:51

      Que peut-on tirer de ces quelques commandes ? Oracle accepte d’ajouter des valeurs entières ou fractionnaires à des données de type DATE ou TIMESTAMP. Les valeurs ajoutées sont considérées en JOURS. Par exemple, 1/1440 représente 1 minute.
      Place à présent à PostgreSQL dans sa version 9.6 :

select version(); version --------------------------------------------------------------------------------------------------- PostgreSQL 9.6.1 on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.2.0-10) 6.2.0 20161027, 64-bit (1 ligne) select to_char(current_date,'DD/MM/YY HH24:MI') as hui, to_char(current_date + 1/1440,'DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(current_date+1, 'DD/MM/YY HH24:MI') as demain ; hui | une_minute_plus_tard | demain ----------------+----------------------+---------------- 18/12/16 00:00 | 18/12/16 00:00 | 19/12/16 00:00 (1 ligne) select to_char(current_timestamp,'DD/MM/YY HH24:MI') as hui, to_char(current_timestamp + 1/1440,'DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(current_timestamp+1, 'DD/MM/YY HH24:MI') as demain ; ERREUR: l’opérateur n’existe pas : timestamp with time zone + integer LIGNE 1 : ...MM/YY HH24:MI') as hui, to_char(current_timestamp + 1/1440,'... ^ ASTUCE : Aucun opérateur ne correspond au nom donné et aux types d'arguments. Vous devez ajouter des conversions explicites de type. select to_char(current_timestamp,'DD/MM/YY HH24:MI') as hui, to_char(current_timestamp + interval '1 minute','DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(current_timestamp + interval '1 day', 'DD/MM/YY HH24:MI') as demain ; hui | une_minute_plus_tard | demain ----------------+----------------------+---------------- 18/12/16 04:41 | 18/12/16 04:42 | 19/12/16 04:41 (1 ligne) select to_char(current_timestamp,'DD/MM/YY HH24:MI') as hui, to_char(current_timestamp + cast('1 minute' as interval),'DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(current_timestamp + cast('1 day' as interval), 'DD/MM/YY HH24:MI') as demain ; hui | une_minute_plus_tard | demain ----------------+----------------------+---------------- 18/12/16 04:44 | 18/12/16 04:45 | 19/12/16 04:44 (1 ligne) select to_char(current_timestamp,'DD/MM/YY HH24:MI') as hui, to_char(current_timestamp + interval '1' minute,'DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(current_timestamp + interval '1' day, 'DD/MM/YY HH24:MI') as demain ; hui | une_minute_plus_tard | demain ----------------+----------------------+---------------- 18/12/16 04:46 | 18/12/16 04:47 | 19/12/16 04:46 (1 ligne)

      Les DATES Oracle ont une précision à la seconde, les DATES PostgreSQL sont précises à la journée. Ajouter un entier à une DATE est donc accepté par PostgreSQL. Il n’y a aucune ambiguïté : il s’agit d’ajouter un intervalle exprimé en JOURS à cette DATE.
      En revanche, il est impossible d’ajouter un entier ou autre valeur numérique à un TIMESTAMP avec PostgreSQL. Il faut ajouter un INTERVAL et plusieurs syntaxes sont acceptées.
      Une ou plusieurs de ces syntaxes sont-elles acceptées par Oracle Database ? Démonstration avec Oracle Database 11.2.0.2 :
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production SQL> select to_char(current_timestamp,'DD/MM/YY HH24:MI') as hui, to_char(current_timestamp + interval '1 minute','DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(current_timestamp + interval '1 day', 'DD/MM/YY HH24:MI') as demain from dual; select to_char(current_timestamp,'DD/MM/YY HH24:MI') as hui, to_char(current_timestamp + interval '1 minute','DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(current_timestamp + interval '1 day', 'DD/MM/YY HH24:MI') as demain from dual * ERROR at line 1: ORA-30089: missing or invalid datetime field SQL> select to_char(current_timestamp,'DD/MM/YY HH24:MI') as hui, to_char(current_timestamp + cast('1 minute' as interval),'DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(current_timestamp + cast('1 day' as interval), 'DD/MM/YY HH24:MI') as demain ; select to_char(current_timestamp,'DD/MM/YY HH24:MI') as hui, to_char(current_timestamp + cast('1 minute' as interval),'DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(current_timestamp + cast('1 d ay' as interval), 'DD/MM/YY HH24:MI') as demain * ERROR at line 1: ORA-30089: missing or invalid datetime field SQL> select to_char(current_timestamp,'DD/MM/YY HH24:MI') as hui, to_char(current_timestamp + interval '1' minute,'DD/MM/YY HH24:MI') as une_minute_plus_tard, to_char(current_timestamp + interval '1' day, 'DD/MM/YY HH24:MI') as demain from dual; HUI UNE_MINUTE_PLUS DEMAIN -------------- --------------- -------------- 18/12/16 12:11 18/12/16 12:12 19/12/16 12:11

      Bingo ! Au moins une des syntaxes permettant d’ajouter un INTERVAL à un TIMESTAMP est acceptée par PostgreSQL comme Oracle. Il est donc possible, si vous le souhaitez, de produire un code commun sur cet aspect avec ces 2 SGBD.

Mise à jour : 18/12/2016