SAS Date format convert - date

I've excel file shown below as input,
Report Name Address June14,2019 June 15,2019
Daily CH CJ MJ
After i used below syntax to import
proc import out=ds_new datafile="/Sasdata/SAS_Reports_Tracker_2019.xlsx"
dbms=xlsx replace;
sheet="SAS_Reports_June19";
run;
I'm not getting same output as input, I'm getting as
Report Name Address 43586 43587
Daily CH CJ MJ
Both Dates (June14,2019 June 15,2019) has converted to SAS internal Date format, However i need exact same output as input.

By default, a SAS variable name cannot contain a comma.
Try using the VALIDVARNAME option.
options validvarname=any;
libname data xlsx "/home/loicpalma0/stackoverflow.xlsx";
data want;
set data.sheet1;
run;
However, this is not recommended. You will have trouble at a later stage if you want to perform operations using those two columns. You will have to use "<columns>"n otherwise it will return an error.
Use options validvarname=v7; to change the columns name to a valid SAS name, which are for SAS 7 and later:
Up to 32 mixed-case alphanumeric characters are allowed.
Names must begin with an alphabetic character or an underscore.
Invalid characters are changed to underscores.
Any column name that is not unique when it is normalized is made unique by appending a counter (0, 1, 2, and so on) to the name.
And if you want to see the output with a comma, just use the label option
proc print data=want label;run;
                                        
PS: Note that in the example you provide, you specify 5 columns and only fill 4 of them.

When SAS retrieves an Excel DATE value as text instead of numeric you get the raw Excel value converted to text instead of the number as displayed by Excel formats. Since a variable name is by definition character any date values in column headers will be imported in that way.
First transpose the data to get the variable's name into the value of an actual variable.
proc transpose data=ds_new out=ds_tall ;
by Report Name Address ;
var '4'n: ;
run;
Then convert the digit string into a date value by converting it to an integer and adjusting for the different base date used to count dates.
data want;
set ds_tall;
date = input(_name_,32.) + '30DEC1899'd ;
format date date9.;
run;

Related

how to convert best12. to date9 SAS

Good afternoon
so I have BEST12.
I want to convert to date9.
so my code is
data step7_1;
set step7;
service_day2= input(put(datedate, z8.),yymmdd8.);
format service_day2 date9.;
run;
the error is
NOTE: Invalid argument to function INPUT at line 92 column 15.
NOTE: Mathematical operations could not be performed at the following places. The results of the
operations have been set to missing values.
Each place is given by: (Number of times) at (Line):(Column).
4 at 97:15
how can I fix this issue?
Thanks
Kazu
A format is just a mechanism of displaying data, so there's no need to apply functions to 'convert' it, just apply a format using the format statement:
data step7_1;
set step7;
service_day2 = datedate;
format service_day2 date9.;
run;
If you don't need a new variable, you can just use the format statement alone:
data step7_1;
set step7;
format datedate date9.;
run;
Or you can just alter the original dataset directly using PROC DATASETS:
proc datasets lib=work nolist;
modify step7;
format datedate date9.;
quit;
This has the advantage of not copying data, it will run more quickly and simply modifies the dataset metadata in place.

How to Define date format from a given date

I wanted to know, how can we define date format from given date
for example, i have date 20180423 then in sas I want to define format as 'yyyymmdd'
similarly , i have date given in data as 12022018 then i want to define as 'ddmmyyyy'
Please note that, date is provided to me in proper date, but i want to define format now.
Date given may be different in future
so I need to take care all of the date format through SAS
What I thought was given date 20180422
use substr function
data test;
a=20180422;
a=substr(a,1,4);
b=substr(a,5,1);
c=substr(a,7,1);
run;
but not sure.
If anyone can provide the solution,then it really helps me in my project work.
Thanks in Advance for help.
It sounds like you want to convert various values to a date. SAS stores dates as a number, being the number of days since 1st Jan 1960. It's then usual to format this number to display as a date, in whichever format is preferred.
When importing dates that's are already in a format, it is necessary to use the input function, along with an informat, to convert the formatted value to a SAS date. If the date values being read in are all in the same format, then the specific informat can be used. In your case, where different formats are used, you can use the anydtdte. informat which will convert most of the standard date formats to a SAS date.
The example below converts 3 different date formats to a SAS date, then displays the SAS date in the date9. format. I've printed both the unformatted and formatted new values to the log, just so you can see they are stored as numbers.
data _null_;
input date_in $20.;
date_out = input(date_in, anydtdte20.);
put date_in date_out date_out :date9.;
datalines;
20180422
12022018
27apr2018
;
run;
Use the input(a,anydtdte20.); this will convert any date to SAS date, then use the functions Year(), Month(), Day() to extract the data you want.
You will find this SAS Post very useful about dates and locales.
Solution:
I created a table with two rows; each row have a different date format YYYYMMDD & DDMMYYYY to show you how the code will handles different date formats, saved them to SAS date and broke them down to Year, Month & Day:
options DATESTYLE=DMY;
data have;
input a;
datalines;
20180422
12022018
;
run;
data test;
set have;
format date_a date9.;
date_a=input(a,anydtdte20.);
Year_a=year(date_a);
month_a=month(date_a);
day_a=day(date_a);
run;
Output:
a=20180422 date_a=22APR2018 Year_a=2018 month_a=4 day_a=22
a=12022018 date_a=12FEB2018 Year_a=2018 month_a=2 day_a=12
You can use an if condition inside a data step. Using If condition, check for the condition to be true (check date value satisfies the required criteria), then format the date using a put function.Put function can take a source as first argument and format as second argument , and return the formatted value. Different values of same column, can have different formats specified that way.
Something like this,
if a = 'date1CheckCondtion' then newA = put(a , dateformat1.);
if a = 'date2' then newA = put(a , dateformat2.);
You may then choose to get all values in a common format like this:
dateA=input(newA,mmddyy6.);

Convert Character Date variable to SAS Date

I have the following Variable called Date in an excel file which I'm reading into SAS:
Date
May2005
June2005
July2005
..
July2015
Both the format and the informat are characters ($8)
I wanted to convert these into a SAS Date variable.
How can I accomplish this task?
I thought about using substr to first create a month and year variable,
then use proc format to convert all the months to numeric (e.g 'jan' = 1).
The use the mdy date function to create a new date. But I wonder if there is a shorter way to accomplish this task?
You can use the ANYDTDTE. informat if you prepend a day to your month+year string.
data want ;
set have ;
actual_date = input('01'||date,anydtdte.);
format actual_date date9.;
run;
Note that the FORMAT or INFORMAT attached to the character variable is meaningless, but having a variable of only length 8 will not allow room to store longer month names. Perhaps the length got set to only 8 because your particular example set of data did not include any longer month names.
If you are running such an old version of SAS that the ANYDTDTE. informat does not exist or does not work with fully spelled out months then you will need to work a little harder. You could transform the string into DATE9 format.
actual_date = input
('01'||substr(date,1,3)||substr(date,length(date)-3)
,DATE9.);
As #Tom hints towards, you have to use an informat that SAS can interpret as a numeric value when reading in character dates. I'm not sure if there is one that reads MONTHYYYYw., (naturally, ANYDTDTE works but I prefer to avoid it). In this case, I would use MONYYw., combined with substr to get the length 3 Month abbreviation and the 2 digit year:
data have;
input Date $13.;
datalines;
January2005
Feburary2005
March2005
April2005
May2005
June2005
July2005
August2005
September2005
October2005
November2005
December2005
;
run;
data want;
set have;
Date2 = input(SUBSTR(Date,1,3)||SUBSTR(Date,length(date)-1,2),MONYY13.);
Format Date2 DATE8.;
run;
proc print data = want; run;

Reading/using format YYYYMMDD and "0" values in date field

We have a system feed that's changing...it's currently Julian date and is converting to YYYYMMDD--although for blank values they're feeding in "0". Not sure what format it's coming in as...
First, I took out the 0's by doing "if XXXfield = 0 then XXXfield = ' ' which returns a "." for that record. Then I tried to code using "format XXXfield YYMMDD8." and that's returning blanks for anything with a date. I'm not creating the table, just reading it in....how can I successfully get the date to be a date with no "0" values for blanks and in a format that I can use in SAS (ie XXXfield >= Xdate)?? Thanks in advance for your advice!
Sample Data (one blank and 4 with values):
reporting_date
0
20141122
20130604
20130626
20140930
The format of reporting_date is BEST12. according to your comment below.
data work.have;
input reporting_date BEST12.;
datalines;
0
20141122
20130604
20130626
20140930
;
run;
So, one way to make SAS to interpret reporting_date as an actual date is to temporarly format it as as string and thereafter convert it with YYMMDD10. as the format.
proc sql;
create table work.want as
select input(put(t1.reporting_date, 8.), YYMMDD10.) format=YYMMDDn8. as reporting_date
from work.have t1;
;
run;
In this case,
put converts it to a string with eight characters as the width,
input will convert the string to an actual SAS date, and
format will display the date in a human readable way.
The third bullet is optional, and the value of format is just one of many date and time formats available. The conversion also takes care of rows with 0 as value and transforms them to missing (.).
Now, when you have the column as a SAS date, you are ready to filter it:
proc sql;
create table work.filter as
select t1.reporting_date
from work.want t1
where t1.reporting_date > '01JUL2013'd
;
run;
But instead of make these workarounds, you should look into changing the format in the job where you read this column into the SAS dataset.

SAS and INTNX formatting

I am trying to see if a variable falls into a boundary of dates.
I hate a DATE1 already in MMDDYY10.
I use the following code
DATA GIANT;
SET GIANT;
UPPER_BOUND= intnx('week', DATE1, 2);
run;
it gives me back something in Num 8.
I want to restore it to MMDDYY10. so that I can compare it to my other dates.
Two Questions:
How can I convert a NUMERIC of length 8 into a date?
Why does intnx ... designed to work with dates return a numeric and not something in the same format?
I tried to convert it like this:
DATA GIANT;
SET GIANT;
UP_DATE=INPUT(PUT(UPPER_BOUND, 8.), MMDDYY10.);
FORMAT UP_DOS MMDDYY10.;
run;
but now it all comes up as null.
SAS Dates are always numeric (# of days since 1/1/1960). Date formats are simply a way of making that numeric readable. INTNX returns a numeric because that's all a date is; it's up to you to apply a date format to the new variable.
In your case it's very simple. You almost got it right in your attempt, but you don't need the input/put business.
data giant;
set giant;
upper_bound=intnx('week',Date1,2);
format upper_bound MMDDYY10.;
run;
INPUT converts human readable text into a value (usually a number). PUT converts a value into human readable text. PUT(INPUT(...)) is commonly used to convert a formatted value into a different kind of formatted value (for example, to convert the string "1/1/1960" to "01JAN1960"); INPUT(PUT(...)) is not very commonly used unless you are parsing the string that PUT created (such as, to read just a particular date element or something like that). Both change the type (from numeric to character in PUT or other way in INPUT) in most cases and certainly change the actual stored value.
Applying a format to a numeric column leaves the column as a numeric (which is usually good) but tells SAS how to display that numeric so you can understand it (also usually good). So underneath the value is 19857 but what is displayed is 05/14/2014.