I have a very basic question in SAS
I have the following macro variable which is in text format, I want to convert to a date format...not too sure how to do this:
%let mydt = 06/30/1999;
How do I convert this into a date format so that^
%let mydtnew = "06/30/1999"d;
Thanks for your help...
Try this - is that what you were after?
%let mydt = 06/30/1999;
%let mydt2 = %sysfunc(inputn(&mydt,mmddyy10.));
%put &mydt2;
Note that in SAS, date literals should follow DDMMMYYYY (date9.) format.
So, you could use something like this:
%let mydtnew = %sysfunc(putn(%sysfunc(inputn(&mydt., MMDDYY10.)), date9.));
The inner most %sysfunc is telling SAS that the date is in mm/dd/yyyy format - at this stage that text date is stored as a number. The outer %sysfuncis telling SAS to take the numeric date and format it into date9. format.
Note: mydtnew will store date without the double quotes or the d at the end. Usuall practice is to add the quotes and the d at the time you use the macro, such as
where account_open_date>="&mydtnew."d
Related
A little new to SAS here. I am using the following data step to get the first and last day of the month.
Data _NULL_;
begindt=IntNX("Month", Date(), 0) ;
enddt=IntNX("Month", Date(),0,'E');
PUT begindt=E8601DA. enddt=E8601DA.;
Run;
The data step gets the results of begindt=2021-09-01 and enddt=2021-09-30.
However, I am having trouble converting the value to a date format to use in a where claus in a PROC SQL statement later in the program. The commented out code works, but I can't get the date from data step in the correct format for the PROC SQL statement to work.
/* AND "DETAILAR"."CLEAR_DOC_POSTING_DATE" = '2021-09-01' */
AND "DETAILAR"."CLEAR_DOC_POSTING_DATE" = begindt
SAS has date and time literals that make dealing with dates and times easy. SAS dates are the number of days since Jan 1 1960, and SAS datetimes are the number of seconds since Jan 1 1960. SAS automatically converts date literals to these times for you. Some examples of date and datetime literals:
'04SEP2021'd
'04SEP2021:00:00'dt
You don't have to use these all the time*, but they make debugging way easier. In your case, you simply need to feed a date literal into proc sql. If you're connecting to SAP HANA through SAS, the SAS/ACCESS engine to SAP will handle the conversion for you.
data _null_
begindt = intnx('month', today(), 0, 'B');
enddt = intnx('month', today(), 0, 'E');
call symputx('begindt', put(begindt, date9.) );
call symputx('enddt', put(enddt, date9.) );
run;
Or, equivalently:
%let begindt = %sysfunc(intnx(month, %sysfunc(today()), 0, B), date9.);
%let enddt = %sysfunc(intnx(month, %sysfunc(today()), 0, E), date9.);
Now you have two macro variables that you can not only easily read, but SAS will convert them for you. You can view them below:
%put &begindt;
%put &enddt;
Simply add them as date literals to your where clause in proc sql and let SAS do the rest.
proc sql;
create table want as
select *
from have
where CLEAR_DOC_POSTING_DATE BETWEEN "&begindt"d AND "&enddate"d
;
quit;
There are other literals too, like time literals, hex literals and name literals for variables with spaces in them.
'10:00't - Time Literal
'32'x - Hex literal
'this is a var'n - Name literal
*proc timeseries, proc timedata, and proc tsmodel require date/datetime literals for the start and end options. But those are the only ones I know of.
If you want to generate code like '2021-09-01' then why not create a macro variable with that string in it?
In your data _null_ step use:
call symputx('begindt',quote(put(intnx('month',date(),0),yymmdd10.),"'"));
Working from the inside out that statement will:
calculate today's date
convert to the start of the month
convert to a 10 character string representing that date
add single quotes around the string
store the value into a macro variable named begindt
Now you reference the macro variable to generate the code you want
and "DETAILAR"."CLEAR_DOC_POSTING_DATE" = &begindt.
Which will generate the code:
and "DETAILAR"."CLEAR_DOC_POSTING_DATE" = '2021-09-01'
I am trying to convert datatime20. from numeric to character value.
Currently I have numeric values like this: 01Jan200:00:00:00 and I need to convert it to character values and received output like: 2020-01-01 00:00:00.0
What format and informat should be used in aboved ?
I have tried used PUT function to convert numeric to character and tried many option, each time receiving other format. Should be also use DHMS function before PUT ?
There is not a native format that produces that string exactly. But it it not hard to build it in steps using existing formats. Or you could use PICTURE statement in PROC FORMAT to build your own format.
If you don't really care about the time of day part of the datetime value then this is an easy and clearly understand way to convert the numeric variable DT with number of seconds into a new character variable in that style. Use DATEPART() to get the date (number of days) from the datetime value and then use the YYMMDD format to generate the 10 character string for the date and then just append the constant string of the formatted zeros.
length dt_string $21.;
dt_string = put(datepart(dt),yymmdd10.)||' 00:00:00.0';
If you need the time of day part then you could also use the TOD format.
dt_string = put(datepart(dt),yymmdd10.)||put(dt,tod11.1);
Or you could use the format E8601DT21.1 and then change the letter T between the date and time to a space instead.
dt_string = translate(put(dt,E8601DT21.1),' ','T');
If you want to figure out what formats exist for datetime values and what the formatted results look like you could run a little program to pull the formats from the meta data and apply them to a specific datetime value.
data datetime_formats;
length format $50 string $80 ;
set sashelp.vformat;
where fmttype='F';
where also fmtinfo(fmtname,'cat')='datetime';
keep format string fmtname maxw minw maxd ;
format=cats(fmtname,maxw,'.','-L');
string=putn('01Jan2020:01:02:03'dt,format);
run;
A custom format can be defined to return the result of a user defined function. Docs
proc format;
value <format-name> (default=<width>)
other = [<function-name>()]
;
run;
Example:
options cmplib=(sasuser.functions);
proc fcmp outlib=sasuser.functions.temporal;
function E8601DTS (datetime) $21;
return (
translate (putn(datetime,'E8601DT21.1'),' ','T')
);
endsub;
run;
proc format;
value E8601DTS (default=21)
other = [E8601DTS()]
;
run;
data have;
do dt = '01jan2020:0:0'dt to '10jan2020:0:0'dt by '60:00't;
output;
end;
format dt datetime16.;
run;
ods html file='function-based-format.html';
proc print data=have(obs=4); title 'stock E8601DT';
proc print data=have(obs=4); title 'custom E8601DTS';
format dt E8601DTS.;
run;
ods html close;
This is part of a larger query, used to create a table that contains observations within a month, and using that month as the table name.
I'd like the table name to be a sensible looking date, not a numeric.
Why does this %sysfunc(putc()) function not create a character string?
%macro transLiteralDate2Char(dateval=);
%put numerical = &dateval.;
%put sasdatavalue = %sysfunc(putc(&dateval,MONYY5.));
%mend;
%transLiteralDate2Char(dateval=%sysfunc(mdy(3,1,2016)));
A put command in SAS always returns a character string. The distinction between %sysfunc(putc()) and %sysfunc(putn()) is what type of format the second argument of the function is - putc understands character formats and putn understands numeric formats. In this case, because date formats are numeric, you want to use %sysfunc(putn()) to print your string. Like this:
%macro transLiteralDate2Char(dateval=);
%put sasdatavalue = %sysfunc(putn(&dateval,MONYY5.));
%mend;
%transLiteralDate2Char(dateval=%sysfunc(mdy(3,1,2016)));
Check out the examples here for more info.
You can also use the second parameter in %SYSFUNC()
%put %sysfunc(today(), date9.);
I have a global macro variable from another macro which looks like
'01jan2014' when you print it in the log
i.e. there are enforced quotemarks
I want to use this in a proc sql statement but I can't as it doesn't like the variable type.
How do I convert this into a date in the WHERE clause of my proc sql statement?
%let yourdate = 01Feb2015;
%put &yourdate; /* resolve to 01Feb2015 */
proc sql;
select *
from have
where date ge "&yourdate."d;
or
%let yourdate2 = '01Feb2015'd;
proc sql;
select *
from have
where date ge &yourdate2;
I think the first one is better since it won't contain ' in macro variable.
To convert a date string in DDMONYYYY format, simple add a d to the end.
'01jan2014'd
will convert the string to a date.
In your case:
&var.d
will resolve to
'01jan2014'd
which will be interpreted as a date.
I want to convert a String to Date in SAS, I tried:
data _null_;
monyy = '05May2013';
date = input(substr(strip(monyy),1,9),yymmdd.);;
put date=date9.;
run;
But it did not work. Can this be done?
Formats like
date9.
or
mmddyy10.
are not valid for input command while converting text to a sas date. You can use
Date = input( cdate , ANYDTDTE11.);
or
Date = input( cdate , ANYDTDTE10.);
for conversion.
You don't need substr or strip.
input(monyy,date9.);
As stated above, the simple answer is:
date = input(monyy,date9.);
with the addition of:
put date=yymmdd.;
The reason why this works, and what you did doesn't, is because of a common misunderstanding in SAS. DATE9. is an INFORMAT. In an INPUT statement, it provides the SAS interpreter with a set of translation commands it can send to the compiler to turn your text into the right numbers, which will then look like a date once the right FORMAT is applied. FORMATs are just visible representations of numbers (or characters). So by using YYMMDD., you confused the INPUT function by handing it a FORMAT instead of an INFORMAT, and probably got a helpful error that said:
Invalid argument to INPUT function at line... etc...
Which told you absolutely nothing about what to do next.
In summary, to represent your character date as a YYMMDD. In SAS you need to:
change the INFORMAT - date = input(monyy,date9.);
apply the FORMAT - put date=YYMMDD10.;
Try
data _null_;
monyy = '05May2013';
date = input(substr(strip(monyy),1,9),date9.);
put date=date9.;
run;
input(char_val, date9.);
You can consider to convert it to word format using
input(char_val, worddate.)
You can get a lot in this page http://v8doc.sas.com/sashtml/lrcon/zenid-63.htm
This code helps:
data final; set final;
first_date = INPUT(compress(char_date),date9.); format first_date date9.;
run;
I personally have tried it on SAS
input(char_val,current_date_format);
You can specify any date format at display time, like set char_val=date9.;