BookmarkSubscribeRSS Feed
jerrylshen
Obsidian | Level 7
*Imported SAS file named "sv1"

data sv;
	set sv1 ;
	by subject;
	char_date = input(SVSTDTC,date8.); 
	format char_date date9. ;
run;

proc print data=sv;
run;
 
/* Edit: I also tried these but no good still:
* char_date = input(SVSTDTC, date15.);
* format char_date date15. ;
 *
* char_date = input(SVSTDTC, date15.);
* format char_date date9. ;
 */

Screenshot (124).png

 

 

I'm trying to find the days difference using INTCK, but it says that the date SVSTDTC has to numeric, so I'm trying to reformat SVSTDTC. But the year output is all messed up for some reason.

Any help?

Thanks

 

11 REPLIES 11
Astounding
PROC Star

Your incoming date string is 10 characters long.  But you read it with an informat that reads only 8 characters.  Try:

 

char_date = input(SVSTDTC,date10.);
jerrylshen
Obsidian | Level 7
Nope, changing it to "char_date = input(SVSTDTC, date10.);" didn't fix it, still 2020 as year:'(
Astounding
PROC Star

Looks like some of your incoming date strings are even longer than 10 characters.  Play with it.  Try date11. or date12.

jerrylshen
Obsidian | Level 7

Yeah I tried both and still no good:

 

char_date = input(SVSTDTC, date15.);
format char_date date9. ;


char_date = input(SVSTDTC, date15.);
format char_date date15. ;
Tom
Super User Tom
Super User

We cannot tell what actual values your character variable has from Polaroids of your screen.

 

Try this:

  • remove leading spaces from the string
  • Use a longer width on the informat
data test;
  input string $char20.;
  date1=input(string,date11.);
  date2=input(left(string),date11.);
  format string $char20. date: date9.;
*---+----0----+----0;
cards;
1/JAN/2017
 2/JAN/2017
  3/JAN/2017
   4/JAN/2017
    5/JAN/2017
     6/JAN/2017
      7/JAN/2017
       8/JAN/2017
        9/JAN/2017
         1/JAN/2017
;

proc print;
run;
Obs    string                      date1        date2

  1    1/JAN/2017              01JAN2017    01JAN2017
  2     2/JAN/2017             02JAN2017    02JAN2017
  3      3/JAN/2017                    .    03JAN2017
  4       4/JAN/2017           04JAN2020    04JAN2017
  5        5/JAN/2017          05JAN2002    05JAN2017
  6         6/JAN/2017                 .    06JAN2017
  7          7/JAN/2017                .    07JAN2017
  8           8/JAN/2017               .    08JAN2017
  9            9/JAN/2017              .    09JAN2017
 10             1/JAN/2017             .    01JAN2017

 

Tom
Super User Tom
Super User

Why would you name a variable that has a numeric value as CHAR_DATE?

 

Why would you use a length of 8 with the DATE informat? It takes 9 characters to show a date with full year.  DDMONYYYY.  With only 2 digit year then it takes 7 characters. If you read only 8 characters you have lost the least significant digit of the year.  Not sure how that would cause the issue you are seeing instead of an error.  01AUG201 is not a valid date.

jerrylshen
Obsidian | Level 7
I copy/pasted code from other solutions when doing this, but good point, I'll change the name afterwards.

I tried "char_date = input(SVSTDTC, date9.);" but still no good:/
ballardw
Super User

You are actually hiding you data by showing pictures. Pictures do not show values.

Instructions here: https://communities.sas.com/t5/SAS-Communities-Library/How-to-create-a-data-step-version-of-your-dat... will show how to turn an existing SAS data set into data step code that can be pasted into a forum code box using the {i} icon or attached as text to show exactly what you have and that we can test code against.

 

Please note:

data example;
   svstdtc= '1/Jan/2019';
   char_date1 = input(SVSTDTC,date8.);
   char_date2 = input(SVSTDTC,date10.);
   format char_date1 char_date2 date9. ;
run;
ods listing;
proc print;run;
ods listing close;

Creates

                         char_        char_
Obs     svstdtc          date1        date2

 1     1/Jan/2019    01JAN2020    01JAN2019

When you read

1/Jan/2019 with date8 format it stops reading

            ^

And so treats the input string as if the 20 were the last 2 digits as 2020 because it looks similar to date7 : 01JAN20

 

10/Jan/2019 gets treated as 10Jan2002 because the 8th character is the 2 and so you have told SAS that is entire "year" value it should use for the input and again less than a 4 year value is treated as 2 digits, i.e. 02.

DATE10 will not work with 10/Jan/2019 because that would attempt to use a 3 digit year and that just isn't allowed.

 

I would suggest:

   if length(svstdtc)=10 then char_date1 = input(SVSTDTC,date10.);
   else if length(svstdtc)=11 then char_date1 = input(SVSTDTC,date11.);

If you have some with actual 2 digit years then you need to add in cases for lengths of 8 and 9 as well.

 

 

Tom
Super User Tom
Super User

Note that there is no need to check length of input string. The DATE informat supports widths up to 32.  The INPUT function does not mind if the string is shorter than the width of the informat being used.

526   data test;
527     dt=input('01jan2019',date32.);
528     format dt date9.;
529     put dt=;
530   run;

dt=01JAN2019
PaigeMiller
Diamond | Level 26
char_date = input(compress(svstdtc,'/'),date10.);
--
Paige Miller
Tom
Super User Tom
Super User

@PaigeMiller wrote:
char_date = input(compress(svstdtc,'/'),date10.);

That won't fix it if the issue is leading spaces.  Also there is no need to remove the slashes as the DATE informat works fine with slashes as the delimiter.

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 11 replies
  • 3686 views
  • 1 like
  • 5 in conversation