views:

737

answers:

5

Can anyone advise on the appropriate SAS informat to read in a datetime (dd/mm/yyyy hh:mm) ???

eg

data _null_;
informat from_dt datetime????.;
input from_dt ;
put from_dt=;
cards;
01/01/1960 00:00
;run;
A: 

This entry from the SAS knowledgebase includes code for parsing and formatting datetime. Looks like SAS has a great online help system.

The third message in this exchange on Google groups may be helpful as well. It talks about inputting datetime, and provides code.

Your question is so hard to decipher, and I know so little about SAS, that's about all I can offer. Hope it helps.

Argalatyr
+3  A: 

SAS might not support the specific datetime format your data is in. You could either try to convert the incoming data to a frendlier format or you could parse the datetime using the substr, DHMS and MDY functions:

data test;
    format dtstr $16. dt datetime22.4;
    dtstr='01/01/1960 00:00';
    day=substr(dtstr,1,2);
    month=substr(dtstr,4,2);
    year=substr(dtstr,7,4);
    hour=substr(dtstr,11,2);
    minute=substr(dtstr,15,2);
    dt=DHMS(MDY(1*month,1*day,1*year),1*hour,1*minute,0);
    output;
run;

Or alternatively you could convert the datetime string into a datetimew.d format and input the formatted string:

data test;
    format dtstr $16. dstr $8. tstr $5. indtstr $14. dt datetime22.4;
    dtstr='01/01/1960 00:00';
    dstr=put(input(substr(dtstr,1,10),mmddyy10.),date8.);
    tstr=substr(dtstr,12);
    indtstr=dstr!!':'!!tstr;
    dt=input(indtstr,datetime14.0);
    output;
run;

The conversion can be compressed to a single but complex statement, so creating a macro for this might be a good decision.

Ville Koskinen
A: 

Going by the list here, I don't think there is one.

Conceivably you could create your own with proc format, but I think that would be very difficult. Ville Koskinen's suggestion is probably your best bet.

John Fouhy
+5  A: 

I don't think that specific informat is built-in, but it is relatively easy to roll your own. Below is an example of a creating a custom datetime informat (this requires a cntlin data set) and a custom format (using the picture statement) that reads in your specific datetime and then formats it back out to look the same as the input. I simplified it by assuming the time part was always midnight (00:00), but it can be easily expanded if you need to keep track of the time parts as well (just change the 86400 number to 3600 to get every hour, and 60 for every minute). It helps to see what is going on if you open the work.infmt data set to see what it looks like.

/* Create a custom datetime format as Month/Day/Year<space>Hours:Minutes*/
proc format;
  picture mydt other='%0m/%0d/%0Y %0H:%0M' (datatype=datetime);
run;

/* Create a custom informat using the format above */
data infmt ;
retain fmtname "dtwithspace" type "I" ;
   do label = "1jan1960:00:00"dt to
              "2jan2059:00:00"dt by 86400 ; 
      start = trim(left(put(label,mydt.)));
      output ;
   end ;
run ;
proc format cntlin = infmt ;
run ;


/* Now apply the informat and format to the data */
data _null_;
input from_dt $ 1-20;
format from_dt2 mydt.;
from_dt2=input(from_dt, dtwithspace.);
put from_dt2=;
cards;
01/01/1960 00:00
01/02/1999 00:00
;
run;

This gave an output like this:

278  data _null_;
279  input from_dt $ 1-20;
280  format from_dt2 mydt.;
281  from_dt2=input(from_dt, dtwithspace.);
282  put from_dt2=;
283  cards;

from_dt2=01/01/1960 00:00
from_dt2=01/02/1999 00:00
cmjohns
+4  A: 

The anydt* family of informats do work, usually.

data _null_;
  from_dt = input("01/01/1960 00:00", anydtdtm.);
  put from_dt= :datetime20.;
run;
/* on log
from_dt=01JAN1960:00:00:00
*/
Chang Chung
Nice - I hadn't seen that informat before.
cmjohns