KeepNotes blog

Stay hungry, Stay Foolish.

0%

Assume that you input a character string 20211109 with a sas format like yymmdd8. that specifies how sas must interpret the character string, you will get a numeric number 22593.

What does the number mean? The date value in SAS represents the number of days between January 1st, 1960 and a specified date, before is negative numbers, while after is positive numbers.

data date_1;
input date_char \$8.;
sas_date_value=input(date_char, yymmdd8.);
/*  sas_date_format=put(sas_date_value, yymmdd10.);*/
datalines;
20211109
;
run;

proc contents data=date_1; run;

As the sas date value is not readable for humans, you can use PUT function to convert the date value to SAS date, or just FORMAT statement to apply a format to the variable straightforwardly.

data date_1;
input date_char \$8.;
sas_date_value=input(date_char, yymmdd8.);
sas_date_format=put(sas_date_value, yymmdd10.);
datalines;
20211109
;
run;

data date_2;
input date_char \$8.;
sas_date=input(date_char, yymmdd8.);
format sas_date yymmdd10.;
datalines;
20211109
;
run;

It also happens in R, but the start date is 1970-01-01, instead of 1960-01-01.

x <- as.Date("1970-01-01", "%Y-%m-%d")
> as.numeric(x)
 0

Dates calculation

The most common requirement is to return a person’s age; the YRDIF function can handle it.

data c_age;
input date1 date9.;
age=yrdif(date1, today(), "Actual");
format date1 yymmdd10. age 5.1;
datalines;
14JUN1990
03MAY2000
;
run;

In SAS you can calculate the difference between two dates with INTCK functions.

data date_init;
format mydate1 mydate2 yymmdd10.;
input mydate1 :date9. mydate2 :date9.;
datalines;
13JUN2020 18JUN2020
22JUN2020 20JUL2020
01JAN2020 31DEC2020
03MAY2020 19AUG2020
;
run;

Note: if two variables set input format, it’s better to add : in front of format to avoid some unexpected errors.

Firstly, calculate the difference in days.

data data_d;
set date_init;
diff_days_disc=intck("day", mydate1, mydate2)
run;

Then the difference in months is as follows. If you set the argument equal to "C", SAS just calculates the full month between them. So if the number of days is less than one month, the full month number is zero.

data date_m;
set date_init;
diff_months_disc = intck('month', mydate1, mydate2, 'D');
diff_months_cont = intck('month', mydate1, mydate2, 'C');
run;

Then the difference in weeks is as follows, the same as month calculation.

data date_w;
set date_init;
diff_weeks_disc = intck('week', mydate1, mydate2, 'D');
diff_weeks_cont = intck('week', mydate1, mydate2, 'C');
run;

Additionally, if you want to answer the question, what day is the next 5th day? INTNX function is frequently used in that situation.

data _null_;
next_day = intnx("day", today(), 1);
previous_day = intnx("day", today(), -1);

put "Today: %sysfunc(today(), EURDFWKX28.)";
put "Next Day: " next_day EURDFWKX28.;
put "Previous Day: " previous_day EURDFWKX28.;
put "Today +5 Days: " add_5_days EURDFWKX28.;
run;

If you want to extract the day from the SAS date, day function may be an easy way to accomplish. The day function returns the day number that is within this month, however the month number is within this year.

Besides, if you want to extract the week and year combined, the put function may be more appropriate.

data date_extr;
set date_init(keep=mydate1);
ext_day=day(mydate1);
ext_week=week(mydate1);
ext_year=year(mydate1);
monthyear = put(mydate1,monyy7.);
run;

Oppositely MDY function is used to combined the day, month and year data. MYD, YMD, YDM, DMY, DYM are also similar.

In the R, lubridate package provides many convenient functions to produce, convert and conduct date data.

You can use lubridate::ymd(), lubridate::mdy() and lubridate::dmy() convert character string to date format.

ymd(c("1998-3-10", "2018-01-17", "18-1-17"))

If you’re willing to extract day, month and year numbers from date format data, those functions may be useful as follows.

> mday(as.Date("2021-11-09"))
 9
> month(as.Date("2021-11-09"))
 11
> year(as.Date("2021-11-09"))
 2021

We can add or subtract the date directly, but sometimes the difftime function is a better choice.

x <- as.Date(c('2021-09-01', '2021-11-01'))
> c(difftime(x, x, units='days'))
Time difference of 61 days

In addition, dseconds(), dminutes(), dhours(), ddays(), dweeks(), dyears() functions are convenient if you want to return the day of the 5th day from today.

d <- ymd("2021-11-09")
> d + ddays(5)
 "2021-11-14"