BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Moksha
Pyrite | Level 9

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
01JAN202201JAN60:02:44:22202231960-01-01T06:17:26
1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

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

 

View solution in original post

9 REPLIES 9
ballardw
Super User

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

 

Moksha
Pyrite | Level 9

Thanks Kurt, I have corrected julian date.

Moksha
Pyrite | Level 9

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: 


Obs doj dob datejulian dateiso1
01JAN202201JAN87:00:00:0010JAN202301JAN22:12:05:00
Moksha
Pyrite | Level 9

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:

Obs doj dob datejulian dateiso1
01JAN202201JAN87:00:00:0010JAN20232022-01-01T12:05:00
Tom
Super User Tom
Super User

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

 

Moksha
Pyrite | Level 9

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 Innovate 2025: Call for Content

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 16. Read more here about why you should contribute and what is in it for you!

Submit your idea!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 9 replies
  • 1454 views
  • 0 likes
  • 4 in conversation