Dates sous SAS

Tout sur les formats et fonctions de base

Une date SAS est stockée sur 4 octets sous la forme d'un nombre de jours depuis le 1er janvier 1960. Ainsi toute édition brute d'une date aboutira à l'affichage d'un nombre entier, ce qui parfois déroute les débutants. Il faut noter par ailleurs que ce nombre de jours peut être négatif si la date est antérieure au 1er janvier 1960.

SAS compte deux autres formats temporels, datetime et time, stockés sur 8 octets. Ces derniers descendent au niveau de la seconde.

Formatage d'une date

Affichons sans plus attendre la date du jour :


data class;
 date_jour = today();
 run;
SAS date datetime

Comme vous pouvez le noter, la date du jour peut être récupérée via la fonction today(). Par ailleurs, comme nous l'avons dit en introduction, la variable, ici date_jour, est initialisée avec le nombre de jours qui sépare le 1er janvier 1960 de la date du jour. Nous allons devoir formater la date via l'instruction format, ci-dessous un exemple :


data class;
 date_jour = today();
 format date_jour date9.;
 run;
SAS date datetime

Nous avons utilisé le format date9. mais il en existe beaucoup d'autres. La documentation SAS en ligne en dresse une liste.

Extraction d'informations depuis une date

Nous l'avons vu dans la section précédente, il est possible d'extraire à l’édition certaines informations comme le mois, le jour, etc ... Il existe cependant un certain nombre de fonction prévues à cet effet. En voici quelques-unes :

DAY(...), MONTH(...) et YEAR(...)

DAY(date)

MONTH(date)

YEAR(date)

Ces 3 fonctions parlent d'elles-mêmes, elles consistent à extraire le jour, le mois ou l'année d'une date donnée. Ci-dessous un exemple :


data class;
 date_depart="17JAN2023"d;

 jour  = DAY(date_depart);
 mois  = MONTH(date_depart);
 annee = YEAR(date_depart);

 format date_depart date9.;
 run;
SAS date datetime

INTCK(...)

INTCK(unite, date_debut, date_fin, methode)

La fonction INTCK retourne l'intervalle dans l'unité demandée entre deux dates. A noter que le 4e argument (méthode) est facultatif, il désigne la méthode, continue ou discrète, utilisée pour calculer la différence. Nous allons en reparler. Ci-dessous une utilisation basique de INTCK :


data class;
 date_jazz_singer="06OCT1927"d;
 nb_annees = intck('year', date_jazz_singer, today());
 nb_mois   = intck('month', date_jazz_singer, today());
 nb_jours  = intck('day', date_jazz_singer, today());
 format date_jazz_singer date9.;
 run;
SAS date datetime

Nous apprenons donc que, au jour où nous écrivons ces lignes, 96 ans, 1149 mois ou encore 34984 jours se sont écoulés depuis le premier film sonore. year, month et day constituent les intervalles de base, mais il en existe de nombreux autres (cf documentation SAS).

Revenons sur la méthode de calcul, continue ou discrète, de l'intervalle. Pour ce faire, voici un simple exemple avec lequel nous allons déterminer la différence en mois entre une première date au 17 janvier puis une seconde au 03 mars :


data class;
date_depart="17JAN2023"d;
date_arrivee="03MAR2023"d;

/* Calcul methode continue */
nb_mois_c  = intck('month', date_depart, date_arrivee, 'C');

/* Calcul methode discrete */
nb_mois_d  = intck('month', date_depart, date_arrivee, 'D');

format date_depart date_arrivee date9.;
run;
SAS date datetime

INTNX(...)

INTNX(unite, date_debut, increment, alignement)

La fonction INTNX permet d'incrémenter une date d'un pas dont l'unité est spécifiée. L'argument unité a la même signification que celui que nous avons vu pour la fonction précédente. L'incrément est un entier qui peut être négatif, nul ou positif. Enfin, l'alignement, qui est facultatif, va permettre d'indiquer si la date retournée est calée sur le début de l'intervalle (B), la fin (E), le milieu (M) ou le même jour que celui de la date de départ (S). Ci-dessous un exemple :


data class;
date_depart="17JAN2023"d;

date_arriveeB  = intnx('month', date_depart, 2, 'B');
date_arriveeE  = intnx('month', date_depart, 2, 'E');
date_arriveeM  = intnx('month', date_depart, 2, 'M');
date_arriveeS  = intnx('month', date_depart, 2, 'S');

format date_depart date_arriveeB date_arriveeE date_arriveeM date_arriveeS date9.;
run;
SAS date datetime

YRDIF(...)

YRDIF(date_debut, date_fin, base)

Plus spécifique, la fonction YRDIF permet de calculer la différence, en années, entre deux dates. A la différence de INTCK, vue précédemment, il est possible de spécifier via le dernier argument, facultatif, la base de calcul. SAS calcule en effet tout d'abord le nombre de jours entre les deux dates spécifiées puis divise par le nombre de jours d'une année. C'est cette base de calcul qu'il est possible de spécifier. Ainsi, l'argument base peut prendre les valeurs suivantes :

30/360 Chaque mois compte 30 jours, chaque année en compte 360
ACT/ACTSAS tient compte du nombre réel de jours pour chaque mois et chaque année. Les années bisextiles sont également prises en compte
ACT/360Chaque année compte 360 jours
ACT/365Chaque année compte 365 jours
AGEIl s'agit de la valeur par défaut de cet argument. Elle spécifie à la fonction de calculer l’âge d'un individu ou autre entre les deux dates spécifiées.

DATDIF(...)

DATDIF(date_debut, date_fin, base)

La fonction DATDIF est identique à la fonction YRDIF excepté le fait que la différence est retournée en jours et non en années. La base de calcul est la même que spécifiée précédemment.

Initialisation d'une date

Date du jour

Nous l'avons déjà vu au début de cet article, la date du jour peut être récupérée via la fonction today(), mais également date() qui est équivalente.


data class;
  date_jour1 = today();
  date_jour2 = date();
  
  format date_jour1 date_jour2 date9.;
  run;
SAS date datetime

Import de dates

Il est une notion importante sous SAS : informat, qui indique en quelque sorte comment la donnée doit être lue. Celle-ci est complémentaire de format, que nous avons vu à maintes reprises dans cet article, qui indique comment la données doit être affichée.
Lors de l'import d'une donnée comme la date, indiquer à SAS le format de celle-ci s'avère indispensable, ci-dessous un exemple :


DATA class;
    INPUT @6 date1 mmddyy6. @13 date2 mmddyy8. @22 date3 mmddyy10.;
    FORMAT date1 date2 date3 DATE9.;
    DATALINES;
    170723 17-07-23 17 07 2023
    ;
RUN;
SAS date datetime

Dans le code ci-dessus nous importons 3 dates formatées différemment. Via l'instruction input nous spécifions à SAS ou lire les données et surtout dans quel format les lire. Ensuite via l'instruction format, nous lui spécifions comment les afficher.
Attention aux dates dont le siècle est spécifié sur 2 caractères, il peut en effet être nécessaire de préciser l'année de cutoff à SAS via l'option YEARCUTOFF.

Instanciation directe

Constituer une variable date à la volée sous SAS peut s'avérer très utile. Ceci peut être réalisé via l'instruction MDY() qui accepte comme arguments 3 entiers : le mois, le jour et l'année :


data class;
 date_base = today();
 nouvelle_date = mdy(MONTH(date_base), 10, YEAR(date_base)+3);
 format date_base nouvelle_date date9.;
 run;
SAS date datetime

Quelques mots sur Datetime

Comme nous l'avons dit, datetime porte l'information du temps en seconde. La logique sous-jacente est la même que tout ce que nous avons vu précédemment. Ci-dessous un exemple reprenant diverses manipulations :


data class;
 /*Aujourd'hui ... */
 date_base = today();
 
 /* a 12h 40 minutes et 38 secondes ... */
 temps_base = DHMS(date_base, 12, 40, 38) ;
 
 /* il etait : */
 heure = hour(temps_base); 
 minute = minute(temps_base); 
 second = second(temps_base);

 /* ou tout simplement : */
 temps = timepart(temps_base) ; 
 date  = datepart(temps_base) ;

 format date_base date date9.;
 format temps_base datetime.;
 format temps time.;
 run;
SAS date datetime

Crédits

Miniature issue de Image de vecstock sur Freepik


Retrouvez dans la rubrique "Nos datasets" toutes les données dont vous aurez besoin pour tester et pratiquer !