Change SAS date format - date

I have a date variable in ddmmyy8. a format such as 24/12/12, I want to change it to ddmmyy10. format, however, it automatically changes to 24/12/2012, which is not right, the date should be 24/12/1912.
Is there any way to tell SAS it is 1912, not 2012? or I have to minus 100 years manually?

How can you tell which dates should be 2012 and which should be 1912?
If your variable is really a SAS date variable then the century was already 2000, you just couldn't see it before because your were using a display format that didn't show the century. You can use intnx() to adjust the value.
want = intnx('year',have,-100,'same');
If you are converting strings into dates then you might be able to use YEARCUTOFF option to have it interpret 12 as 1912 instead of 2012.
857 %let optsave=%sysfunc(getoption(yearcutoff));
858 %put &=optsave;
OPTSAVE=1926
859 %put %sysfunc(inputn(24/12/12,ddmmyy8),date9);
24DEC2012
860 options yearcutoff=1912;
861 %put %sysfunc(inputn(24/12/12,ddmmyy8),date9);
24DEC1912
862 options yearcutoff=&optsave;

Related

Subtract date from macro variable

I'm having trouble subtracting a date from a Macro Variable.
Currently, I create a macro variable by running:
%LET date = %SYSFUNC(TODAY(),MMDDYY10.);
I feel like I should be able to subtract 1 day from &date by doing the following:
%LET newDate = %SYSFUNC(%INTNX('day',&date,-1),date9.);
However, this produces the error:
ERROR: Function name missing in %SYSFUNC or %QSYSFUNC macro function reference.
I need the output for &newDate to be in date9.
Any help would be appreciated, thanks!
Quick answer:
%LET date = %SYSFUNC(TODAY());
%LET newDate = %SYSFUNC(INTNX(day,&date,-1),date9.);
%put &=newdate;
Explanation:
Firstly, best to remove the formatting from &date to ensure it is interpreted correctly as a date. Your original code resolved (today) inside intnx() to 12/06/2016, which then resolved to 12 divided by 6 divided by 2016 - etc.
Secondly, the inner function to %sysfunc() should be a datastep function - indeed, the whole point of %sysfunc() is to bring these functions into sas. %intnx() isn't a macro function, but if if was, then by definition you wouldn't need to wrap it in %sysfunc().
Finally, the 'day' parameter shouldn't be quoted - everything in sas macro is treated as text by default.
#RawFocus, you are correct that there is no need to format the original date (today's date), and it is easier to deal with that way.
Just for completeness, if someone wanted to apply the MMDDYY10. format, this is how it could be done:
%LET date = %SYSFUNC(TODAY(),mmddyy10.);
%LET newDate = %SYSFUNC(INTNX(day,%SYSFUNC(INPUTN(&date,mmddyy10)),-1),date9.);
%put &=date &=newdate;

SAS Convert string storing date as DDMonYY (date7.) to SAS Date

I have dataset with dates stored as strings in a format ddMonyy e.g. 19Dec16.
When converting the strings using date7. informat to SAS date, some years are interpreted as 19yy and some as 20yy.
Here is a sample code
data strDates;
infile cards;
input StringDate $;
cards;
31Dec99
01Jan00
19Dec16
31Dec25
01Jan26
;
run;
data convertTest;
set strDates;
format Date date9.;
Date=input(StringDate,date7.);
run;
Running the code today (19 Dec 2016) produces the following results
strDate date
31Dec99 31DEC1999
01Jan00 01JAN2000
19Dec16 19DEC2016
31Dec25 31DEC2025
01jan26 01JAN1926
Dates between 01Jan00 and 31Dec25 are assigned to years 2000-2025 while dates from 01Jan26-31Dec99 are treated as years 1926-1999
Question:
How is it determined if 2000 or 1900 is to added to the year? I suspect it is dependent on the runtime (calendar year when the code is run?) - but I was not able to find any reference to this in SAS documentation.
There is an option, YEARCUTOFF, which depending on your system and version probably has a value of either 20 or 26. See KB note 46368 for more information on the change.
It sounds like you're using SAS 9.4, which means the default is 26: anything from 0-25 will be '20xx' and anything from 26-99 will be '19xx'. You can change the YEARCUTOFF option if that value does not work for your data (or, construct the 4 digit year yourself).

SAS: Get current year in YY format

I want to assign the current year in a YY format to either a macro or data set variable.
I am able to use the automatic macro variables &sysdate or &sysdate9 to get the current date. However, extracting the year in a YY format is proving to be a nightmare. Below are some examples of what I've been trying.
There exists the YEARw. format. But when I try to use it I get errors or weird results. For instance, running
data _null_;
yy = year(input("&sysdate9.", year2.));
put yy=;
run;
produces the error
ERROR 48-59: The informat YEAR was not found or could not be loaded.
If I try to format the variable in the output, I get 1965 instead of the current year. The following
data _null_;
yy = year(input("&sysdate9.", date9.));
put yy= yy year2.;
run;
outputs
yy=2016 65
Please help.
This works to get you the 2-digit year number of the current year:
DATA _NULL_;
YEAR = PUT(TODAY(),YEAR2.);
PUT YEAR;
RUN;
/* Returns: 16 */
To breakdown what I am doing here:
I use TODAY() to get the current date as a DATE type. &SASDATE needs to be converted to a DATE, but also it is the date that the SAS session started. TODAY() is the current date.
PUT allows us to pass in a non-character (numeric/date) value, which is why it is used with TODAY() as opposed to INPUT.
I think it is worth exploring the issues here in more detail.
First, Formats are patterns for converting numeric values to a human readable format. That's what you want to do here: convert a date value to a human readable format, in this case to a year.
Informats, on the other hand, convert human readable information to numeric values. That's not what you're doing here; you have a value already.
Second, put matches with Formats, and input matches with informats, exclusively.
Third, you get close in your last try: but you misuse the year format. Formats are basically value mappings, so they map every possible numeric value in their range (sometimes "all values" is the range, sometimes not) to a display value (string). You need to know what kind of value is expected on the input. YEARw. expects a date value as input, not a year value: meaning input is "number of days from 1/1/1960", mapped to "year". So you cannot take a value you've already mapped to a year value and map it again with that method; it will not make any sense.
Let's look at it:
data _null_;
yy = year(input("&sysdate9.", date9.));
put yy= yy year2.;
run;
yy contains the result of the year function - 2016. Good so far. Now, you need the 2 digit year (16); you can get that through mod function, if you like, or put/substr/input:
data _null_;
yy = input(substr(put(year(input("&sysdate9.", date9.)),4.),3,2),2.);
put yy=;
run;
mod is probably easier though since it's a number. But of course you could've used year:
data _null_;
yy = put(input("&sysdate9.", date9.),year2.);
put yy=;
run;
Now, yy is character, so you could wrap that with input(...,2.) or leave it character depending on your purposes.
Finally - a use note on &sysdate9.. You can easily make this a date without input:
"&sysdate9."d
So:
yy = put("&sysdate9."d,year2.);
That's called a date literal (and "..."dt and "..."t also work for datetime,time). They require things in the standard SAS formats to work properly.
And as pointed out in Nicarus' answer, today() is a bit better than &sysdate9 since it is guaranteed to be today. If you're running this in batch or restart your session daily, this won't matter, but it will if you have a long-running session.
Apply the year function to the date variable
Convert to string
Take last 2 digits
EDIT: change input to PUT
Year = substr(put(year(today()), 4.), 3);

SAS date conversion from text.

Hi I have a date conversion problem in SAS,
I imported an excel file which has the following dates.,
2012-01-09
2011-01-31
2010-06-28
2005-06-10
2012-09-19
2012-09-19
2007-06-12
2012-09-20
2004-11-01
2007-03-27
2008-06-23
2006-04-20
2012-09-20
2010-07-14
after I imported the dates have changed like this
40917
40574
40357
38513
41171
41171
39245
41172
38292
39168
39622
38827
41172
40373
I have used the input function to convert the dates but it gives a strange result.,
the code I used.,
want_date=input(have_date, anydtdte12.);
informat want_date date9.; format have_date date9.;run;
I get very stange and out of the World dates., any idea how can I convert these?
You can encourage SAS to convert the data as date during the import, although this isn't necessarily a panacea.
proc import file=whatever out=whatever dbms=excel replace;
dbdsopts=(dbSasType=( datevar=date ) );
run;
where datevar is your date column name. This tells SAS to expect this to be a date and to try to convert it.
See So Your Data Are in Excel for more information, or the documentation.
From : http://www2.sas.com/proceedings/sugi29/068-29.pdf
Times are counted internally in SAS as seconds since midnight and
date/time combinations are calculated as the number of seconds since
midnight 1 January 1960.
Excel also uses simple numerical values for dates and times
internally. For the date values the difference with the SAS date is
only the anchor point. Excel uses 1 January 1900 as day one.
So add a constant.
EXAMPLES:
SAS_date = Excel_date - 21916;
SAS_time = Excel_time * 86400;
SAS_date_time = (Excel_date_time - 21916) * 86400;
As Justin wrote you need to correct for the different zero date (SAS vs. Excel).
Then you just need to apply a format (if you want to get a date variable to do calculations):
want_date = have_date-21916;
format want_date date9.;
Or convert it to a string:
want_date = put(have_date-21916, date9.);
In either case you can choose the date format you prefer.

sas date - convert today() into yyyymmdd format

How do I convert a SAS date such as "30JUL2009"d into YYYYMMDD format (eg 20090730)?
So for instance:
data _null_;
format test ?????;
test=today();
put test=;
run;
Would give me "test=20090730" in the log...
data _null_;
format test yymmddn8.;
test=today();
put test=;
run;
YYMMDDxw. documentation
%let expectdate1=%sysfunc(putn(%eval(%sysfunc(today())-1),yymmddn8.));
You want to use the format yymmddn8. The 'n' means no separator.
Per http://support.sas.com/kb/24/610.html you can specify B for blank, C for colon, D for dash, N for no separator, P for period, or S for slash.
There is this one that should do the trick too
%let today=%sysfunc(today(),yymmddn8.);
%put &today.;
Everything on the link below
https://communities.sas.com/thread/60111
here's how I did it in macro, but surely there must be a format??!!!
%let today=%sysfunc(compress(%sysfunc(today(),yymmddd10.),'-'));
its weird - the INFORMAT yymmdd8. gives YYYYMMDD result, whereas the FORMAT yymmdd8. gives a YY-MM-DD result!!
You can see all date and time formats in Help tab when you enter 'date' to Index tab and then selecr 'date and time formats'