Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sas informat datetime

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;
like image 460
Allan Bowe Avatar asked Sep 07 '09 13:09

Allan Bowe


3 Answers

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
*/
like image 148
Chang Chung Avatar answered Sep 28 '22 02:09

Chang Chung


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
like image 20
cmjohns Avatar answered Sep 28 '22 01:09

cmjohns


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.

like image 40
Ville Koskinen Avatar answered Sep 28 '22 03:09

Ville Koskinen