sas informat datetime - 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;

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
*/

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

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.

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.

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.

Related

What is the SAS format and informat for "mm/dd/yyyy hh:mm:ss"?

The Question
Please is there a built-in SAS format and informat for datetime in mm/dd/yyyy hh:mm:ss? For example:
06/25/2015 03:02:01 (June 25th 2015, 3 o'clock 2 minute 1 second).
The Background
I am trying to parse a CSV flatfile to a SAS dataset in which a datetime column is currently presented in mm/dd/yyyy hh:mi:ss format. I usually would just read it as a string, and then use the substr() function to pick out the date and time parts (as strings), use informat to resolve the SAS date and time (as numbers), and then combine them together to form a SAS datetime (as numbers). I am guessing there could be a cleaner way to do this and therefore am curious if there is already a built-in SAS datetime for mm/dd/yyyy hh:mm:ss which will enable me to read this in one-parse, like this:
data test;
infile "c:\temp\test.csv" dlm=',' missover;
input
dtvar : <the datetime format for mm/dd/yyyy hh:mm:ss>.
var1 $
var2 $
;
format dtvar DATETIME19.;
run;
I have been doing lots of Google searches on this and no luck. Would be very grateful for this!
EDIT / Update (on additional research efforts and findings)
Following the generous forum responses I have performed a comparison between the bespoke (home-made) format mdyhms and the SAS built-in format mdyampm.
The success factors are:
Format case: be able to display 1748351045 as "06/25/2015 03:02:01"
Informat case: be able to convert "06/25/2015 03:02:01" to 1748351045
The bespoke format mdyhms looks like this:
proc format;
picture mdyhms
other = '%0m/%0d/%Y %0H:%0M:%0S' (datatype=datetime);
run;
The comparison exercise below reveals some interesting observations:
Format case: the bespoke format mdyhms is the winner.
Informat case: the built-in format mdyampm is the winner.
Now the comparison exercise...
Format Case
*** bespoke mdyhms as a format (Winner);
data try_format_mdyhms;
x = "25JUN2015:03:02:01"dt; /* 1750820521 */
put x; /* 1750820521 */
put x:mdyhms.; /* 06/25/2015 03:02:01 */
run;
*** built-in mdyampm as a format (Loser);
data try_format_mdyampm;
x = "25JUN2015:03:02:01"dt;
put x; /* 1750820521 */
put x:mdyampm.; /* 6/25/2015 3:02 AM */
run;
Informat Case
*** bespoke mdyhms as an informat (Loser);
data try_informat_mdyhms;
x = input("06/25/2015 03:02:01",mdyhms.); /* informat fail (error) */
put x;
run;
*** built-in mdyampm as an informat (Winner);
data try_informat_mdyampm;
x = input("06/25/2015 03:02:01",mdyampm.); /* 1750820521 */
put x; /* 1750820521 */
run;
Next step:
Are there any built-in (and/or bespoke) formats that will enable BOTH format and informat as per following success factors:
Format case: be able to display 1748351045 as "06/25/2015 03:02:01"
Informat case: be able to convert "06/25/2015 03:02:01" to 1748351045
(the bespoke mdyhms and built-in mdyampm seem to be able to achieve one of the two, but not both). Or have I missed anything?
There are two informats that can read the text "06/25/2015 03:02:01" and convert it to correct SAS datetime value:
ANYDTDTM and MDYAMPM
Have a look at the stackoverflow answer here for using datetime values. You should be able to update it with:
proc format ;
picture mdyhms
other='%0m/%0d/%0Y %0H:%0M:%0S' (datatype=datetime)
;run ;

Reading custom date time formats with SAS

I have a comma delimited data set whose first 2 rows is like this:
1/13/2010 21:09,3.3
11/30/2010 7:33,7.2
....
In trying to read the data in SAS, I have done this data step below:
data myDataSet;
infile 'sampleData.csv' dlm=',';
input timestamp :mmddyy16. value;
run;
Now that the data is now a SAS data set, I try to view it by doing:
data viewData;
set myDataSet;
format timestamp date9.;
run;
proc print data=viewData;
run;
I observed that the timestamp column output only contains the date and not with the time. I want the timestamp to be read and displayed in a format like "dd-mm-yyyy HH:MM:SS". How do I ensure that in reading the file, the informat is correctly specified and no component of the timestamp is lost?
MMDDYYw is a date informat, not a datetime informat - it only reads days and larger and ignores the time. It has a practical maximum length of 10 (although it allows up to 32) as a result.
You can use MDYAMPM. to read those two dates in, among other informats. That might be the ultimately correct informat, or it might not, depending on the totality of your data; several NLS specific informats might also work. See the SAS informat documentation for more details.

SAS 9.3 DATETIME VARIABLE FORMAT AS DATE

I have a datetime22.3 variable which I would like to display as date.
for eg I want to display 17JUL2006:00:00:00.000 as 07/17/2006
How do I do this?
Thanks.
additional info:
Thanks for all the replies.
Actually, I tried to output it in the date format within proc sql. The output is being printed as ********** (stars). I am not sure what is going on.
I am trying to use INTCK in the following manner but get error. I am not sure what I am doing wrong. I would appreciate your help. Thanks.
PROC FORMAT;
PICTURE DTFMT LOW-HIGH='%0m/%0d/%Y' (DATATYPE=DATETIME);
RUN;
data want;
dt_val1='17JUL2006:00:00:00.000'dt;
dt_val2='17AUG2012:00:00:00.000'dt;
format dt_val1 dt_val2 dt_val3 dtfmt.;
dt_val3=intck('MONTH',dt_val1,dt_val2);
put dt_val3;
run;
You can't apply a standard date format directly against a datetime value, although there are some date formats you can prefix with 'DT' which will display a datetime as a date. Unfortunately the MMDDYY format is not one of these, however you could use DTDATE9. which would format your datetime as '17JUL2006'.
Another option is create your own format using the PICTURE statement, the example below will display the datetime as required.
proc format;
picture dtfmt low-high='%0m/%0d/%Y' (datatype=datetime);
run;
data want;
dt_val='17JUL2006:00:00:00.000'dt;
format dt_val dtfmt.;
run;
put(datepart(datetimevariable),yymmdd10.)
use the same princpiple in a data step
data _null_;
a='17JUL2006:00:00:00.000'd;
put a;
put 'formatted date='a MMDDYY10.;
run;
This is the output from my SAS 9.3
44 data _null_;
45 a = '17JUL2006:00:00:00:000'D;
46 put a;
47 put 'formatted ' a MMDDYY10.;
48 run;
16999
formatted 07/17/2006
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
Formatting dates in SAS can be tricky. One method I've used in a macro is this:
/* get the date time */
%let start_date=%sysfunc(datetime().,10);
/* use the DATETIME informat to format the date */
%let fmt_start_date=%sysfunc(putn(&start_date, DATETIME.));
/* format the datetime as a date */
%put "&fmt_start_date."d;
There's a bunch of different ways to format dates. You could also use the FORMAT statement if you're in a data step:
FORMAT STARTDATE YYMMDD10.;
In this case, the format of the column in the data step would give you YYYY-MM-DD and then you can separate the values and reconstruct from there.
There's additional information about SAS informats for dates here:
http://support.sas.com/documentation/cdl/en/etsug/60372/HTML/default/viewer.htm#etsug_intervals_sect008.htm
And here:
http://support.sas.com/documentation/cdl/en/etsug/63348/HTML/default/viewer.htm#etsug_intervals_sect009.htm
If you need more info or examples, please let me know.
Best of luck!
If you want to display the variable's contents as a date (without changing the underlying value), use a FORMAT statement.
proc print;
format dte mmddyys10.;
run;
proc means;
class dte;
format dte mmddyys10.;
run;
etc. Note that you can also put the FORMAT in a data step, in which case any uses of the variable will automatically pick it up.
data foo;
format dte mmddyys10.;
run;
My answer from a duplicate question:
You need to convert original SAS DATETIME value (think of it as data type) to SAS DATE value using DATEPART() function and apply appropriate format:
proc sql;
create table work.abc2
as select *, DATEPART(a.Billing_Dt) format ddmmyy10. as Bill_date
from abc;
quit;
So the point is, as Keith pointed above, to apply appropriate type of format (e.g. ddmmyy10. is the SAS Date format) to appropriate values = variable content (e.g. (unformatted) 10 is 11th January 1960 if used as date, while it's 01JAN60:00:00:10 if used as Datetime value), so you have to be sure what your values represent and convert the values if needed.
data want;
dt_val1='17JUL2006:00:00:00.000'dt;
dt_you_want=input(substr(put(dt_val1,datetime22.3),1,9),date9.);
format dt ddmmyy10.;
run;
Converts date/time var to char date var:
BLEndDatex = put(datepart(BLEndDateTime),yymmdd10.);
Create numeric sas date without time:
BLEndDate = mdy(SUBSTR(BLEndDatex,6,2),SUBSTR(BLEndDatex,9,2),SUBSTR(BLEndDatex,1,4));
Thanks to Rizier123 & Heemin posting above to the first portion.

SAS datetime formatting as POSIX

I want SAS to format datetimes in a POSIX format. The following gives "2009-11-25 14:44:56" how can I display the milliseconds ?
proc format;
picture POSIX other='%0Y-%0m-%0d %0H:%0M:%0S' (datatype=datetime);
run;
data test;
mydatetime='25nov2009 14:44:56.300'dt;
format newdt POSIX.;
newdt=mydatetime;
put mydatetime= newdt=;
run;
EDIT : I am even taker of ANY way to format datetimes to YYYY-MM-DD HH:M:SS.sss (ISO8601) amazing I can't find this in less than 1 minute
E8601DT23.3 should display your values as you wish, except for the extra "T" separator; SAS seems to require that. If you're putting to a character value you can remove the "T" easily; if you are trying to use a formatted numeric value, I think you would have to live with it.
data test;
mydatetime='25nov2009 14:44:56.356'dt;
format newdt E8601DT23.3;
newdt=mydatetime;
put mydatetime= newdt=;
run;
SAS guide on ISO8601:
http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a003169814.htm
Edit: SAS-L came through on this one ( http://listserv.uga.edu/cgi-bin/wa?A1=ind1303c&L=sas-l#8 ). If you have 9.3 this should work (not in 9.2 or earlier).
proc format;
picture POSIX other='%0Y-%0m-%0d %0H:%0M:%0s' (datatype=datetime);
run;
data test;
mydatetime='25nov2009 14:44:56.300'dt;
format newdt POSIX23.3;
newdt=mydatetime;
put mydatetime= newdt=;
run;
Little s, and include the decimal, and it should work as expected. Thanks to data null for the tip.
This solution only works for values of second from 10-59. It does not work for values of second 0-9. There is no leading zero for values of second 0-9.

SAS datetime format YYYY-mm-dd HH:ii

I am trying to display a datetime in the format yyyy-mm-dd hh:mm (e.g. 2012-12-31 23:59)
In PHP I would normally use the format YYYY-mm-dd HH:ii to get what I want. I have been looking through the SAS knowledge base and the closest I can get is E8601DTw.d which provides 2008-09-15T15:53:00 which includes seconds as well as a "T" where I'd like a space.
Is there a format to do what I'd like? If not, is there a way to create my own? I don't know that much SAS myself I'm just trying to modify an existing system. Any help is appreciated.
If the standard datetime formats provided do not meet your requirements you can create a new format:
PROC FORMAT;
picture MyMSdt other='%0Y-%0m-%0d %0H:%0M' (datatype=datetime);
RUN;
DATA TEST;
mydatetime='25nov2009 14:44:56'dt;
format newdt MyMSdt.;
newdt=mydatetime;
put mydatetime= newdt=;
RUN;
Taken from this example that you can easily customize.

Resources