Hi,
I am trying to understand SAS date formats and I have written the following code, but not getting the correct output for dob, datejulian and dateiso. Please, advise me how to correct it.
data date_format_ex1;
input doj date9. @11 dob date9. @21 datejulian julian5. @29 dateiso date9.;
format doj date9. dob datetime18. datejulian julian5. dateiso is8601dt.;
cards;
01jan2022 01jan1987 2022365 01jan2022
;
run;
proc print data=date_format_ex1;
run;
Output:
01JAN2022 | 01JAN60:02:44:22 | 20223 | 1960-01-01T06:17:26 |
Don't bother to use FORMATTED mode input. Just stick to LIST MODE input. You can use the COLON modifier before the informat to continue to use LIST MODE input even when listing informats in the INPUT statement.
Do not take a date value and pass it to the DATEJUL() function, the number used to represent a date has NOTHING to do with the number used to represent a JULIAN date. The number used to represent 31DEC2022 is 23,010. You asked SAS to interpret 23010 as a julian date, so it decided that 23 is the year 2023 and that 010 meant the tenth day of the year.
Note that with LIST MODE the width of the INFORMAT is ignored, instead the whole next "word" on the line is read, so there is not any need to specify a width.
Also there is a bug in the DATETIME format. If you want it to display four digit years you need to use a width of at least 19 (even though it only takes 18 characters to display a nine character date and an eight character time of day with a one character separator).
data date_format_ex1;
input doj :date. dob :date. datejulian :julian. dateiso :datetime.;
dob=dhms(dob,00,00,00);
format doj date9. dateiso datetime19. datejulian date9. dob datetime19.;
put (_all_) (=/);
put datejulian=comma12.;
cards;
01jan2022 01jan1987 22365 01jan2022:12:05:00
;
Results
doj=01JAN2022 dob=01JAN1987:00:00:00 datejulian=31DEC2022 dateiso=01JAN2022:12:05:00 datejulian=23,010
SAS dates use DAYS as increment. Time and datetime values use SECONDS as the interval. So when you use a Datetime format with a date value you are telling SAS to display the number of days in the value of the variable considered to be seconds. You have told SAS to that for your DOB and DATEISO variables.
Why were you attempting to display time portions of values that were not read with any?
If you need a datetime value and only have a date you need to convert it so that the number of seconds matches your need. The DHMS function will do that.
https://communities.sas.com/t5/SAS-Communities-Library/Working-with-Dates-and-Times-in-SAS-Tutorial/... has a PDF with much information about dates.
@Moksha wrote:
Hi,
I am trying to understand SAS date formats and I have written the following code, but not getting the correct output for dob, datejulian and dateiso. Please, advise me how to correct it.
data date_format_ex1;
input doj date9. @11 dob date9. @21 datejulian julian5. @29 dateiso date9.;
format doj date9. dob datetime18. datejulian julian5. dateiso is8601dt.;
cards;
01jan2022 01jan1987 2022365 01jan2022
;
run;proc print data=date_format_ex1;
run;
Output:
Obs doj dob datejulian dateiso1
01JAN2022 01JAN60:02:44:22 20223 1960-01-01T06:17:26
And your Julian date has 7 digits, so you must use the JULIAN7. informat.
Correction: this was meant as an answer to @Moksha
Thanks Kurt, I have corrected julian date.
Hi ballardw, I have tried to use dhms for dob and got it. I tried to correct other variables also as below: But, I am not sure if datejulian output is correct or not. It gives 10Jan2023 whether I use julian5. (with value 22365) or julian7. (with value 2022365. Can you please explain why it is giving 10Jan2023 and also, the corrections I have carried out are correct or not?
data date_format_ex1;
input doj date9. @11 dob date9. @21 datejulian julian5. @27 dateiso datetime18.;
format doj date9. dateiso datetime18.;
dob=dhms(dob,00,00,00);
datejulian=datejul(datejulian);
format datejulian date9. dob datetime18.;
cards;
01jan2022 01jan1987 22365 01jan2022:12:05:00
;
run;
proc print data=date_format_ex1;
run;
Output:
01JAN2022 | 01JAN87:00:00:00 | 10JAN2023 | 01JAN22:12:05:00 |
I have also changed to use iso8601dt.
data Aculore_date_format_qn_ex1;
input doj date9. @11 dob date9. @21 datejulian julian5. @27 dateiso datetime18.;
format doj date9. dateiso is8601dt.;
dob=dhms(dob,00,00,00);
datejulian=datejul(datejulian);
format datejulian date9. dob datetime18.;
cards;
01jan2022 01jan1987 22365 01jan2022:12:05:00
;
run;
proc print data=Aculore_date_format_qn_ex1;
run;
Output:
01JAN2022 | 01JAN87:00:00:00 | 10JAN2023 | 2022-01-01T12:05:00 |
The argument to the DATEJUL function must be a Julian date, not a SAS date. Please consult the documentation.
Don't bother to use FORMATTED mode input. Just stick to LIST MODE input. You can use the COLON modifier before the informat to continue to use LIST MODE input even when listing informats in the INPUT statement.
Do not take a date value and pass it to the DATEJUL() function, the number used to represent a date has NOTHING to do with the number used to represent a JULIAN date. The number used to represent 31DEC2022 is 23,010. You asked SAS to interpret 23010 as a julian date, so it decided that 23 is the year 2023 and that 010 meant the tenth day of the year.
Note that with LIST MODE the width of the INFORMAT is ignored, instead the whole next "word" on the line is read, so there is not any need to specify a width.
Also there is a bug in the DATETIME format. If you want it to display four digit years you need to use a width of at least 19 (even though it only takes 18 characters to display a nine character date and an eight character time of day with a one character separator).
data date_format_ex1;
input doj :date. dob :date. datejulian :julian. dateiso :datetime.;
dob=dhms(dob,00,00,00);
format doj date9. dateiso datetime19. datejulian date9. dob datetime19.;
put (_all_) (=/);
put datejulian=comma12.;
cards;
01jan2022 01jan1987 22365 01jan2022:12:05:00
;
Results
doj=01JAN2022 dob=01JAN1987:00:00:00 datejulian=31DEC2022 dateiso=01JAN2022:12:05:00 datejulian=23,010
Thank you very much Tom for detailed explanation, corrections and telling how to use list input easily. It worked. What I understand is that 23,010 is the number of days between 1 Jan 1960 and 31 Dec 2022.
SAS dates are counts of days, SAS times and datetimes are counts of seconds. Applying datetime formats (DATETIME and E8601DT) to dates can therefore not work.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.