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.
Related
I have table ABC in which I have column Z of datatype Date. The format of the data is YYYYMMDD. Now I am looking to convert the above format to YYYY-MON-DD format. Can someone help?
You can use to_char
TO_CHAR(Z,'YYYY-MON-DD')
Depending on what the purpose of the reformatting is, you can either explicitly cast it to a VARCHAR/CHAR and define the format, or you can change your display format to however you'd like to see all dates:
ALTER SESSION SET DATE_OUTPUT_FORMAT = 'YYYY-MON-DD';
It's important to understand that if the data is in a DATE field, then it is stored as a date, and the format of the date is dependent on your viewing preferences, not how it is stored.
Since the value of the date field is stored as a number, you have to convert it to date.
ALTER SESSION SET DATE_OUTPUT_FORMAT = 'YYYY-MON-DD';
select to_date(to_char( z ), 'YYYYMMDD');
(adding this answer to summarize and resolve the question - since the clues and answers are scattered through comments)
The question stated that column Z is of type DATE, but it really seems to be a NUMBER.
Then before parsing a number like 20201017 to a date, first you need to transform it to a STRING.
Once the original number is parsed to a date, it can be represented as a new string formatted as desired.
WITH data AS (
SELECT 20201017 AS z
)
SELECT TO_CHAR(TO_DATE(TO_CHAR(z), 'YYYYMMDD'), 'YYYY-MON-DD')
FROM data;
# 2020-Oct-17
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.);
I want to change a date format in SAS to another date informat using the query builder.
I thought it should be as simple as:
INPUT(t1.In_date, MMDDYY10.)
But this returns the following error:
ERROR: INPUT function requires a character argument.
So I played about with it & tried a few things for example:
INPUT("t1.In_date", MMDDYY10.)
This doesn't create an error message but only produces blanks.
I've googled the error message but I can't see a way to solve this problem using the query builder.
The informat of t1.In_date is DATETIME18.
If anyone has any suggestion I would be grateful.
You've got a few problems here.
First, informat is the wrong terminology. Your date variables are dates (numbers) with formats; so, you want to change their format. informat is converting a text string to a number; format is changing how a number (or text string) is displayed.
Second, you have a datetime. Datetimes are stored as the number of seconds from 1/1/1960, while Dates are the number of days. That means that they will be not compatible format-wise. You have to use datepart to convert a datetime to a date (basically, this means dividing by 86400).
So, what you want to do:
put(datepart(t1.in_date),mmddyy10.)
I have imported some data into SAS from some Excel spreadsheets sent to me. When I view the output from the imported table, the date appears as "01APR2014" and maintains chronological order. When I view the column properties the type is "Date" and the length is 8. Both the format and informat are DATE9.
I need to be able to convert this date to week-year and month-year, but no matter what I try I always get Jan, 1960.
Using proc sql, I used the below to get the week-year,
"(put(datepart(a.fnlz_date),weeku3.))|| "-" ||(put(datepart(a.fnlz_date),year.)) as FNLZD_WK_YR,"
but all I got was "W00-1960". I've used the formula above successfully many times before with SAS datetime values.
For month-yr, using proc sql, I tried
"datepart(a.fnlz_date) as DT_FNLZD format=monyy.,"
but the only value returned is "JAN60".
I also tried using SUBSTR, but got an error saying it requires a character argument, so SAS must see it as a number at least.
My question; does anyone know a way to get the week-yr and/or month-yr from this format? If so, how? I'm not opposed to using a data step, but I haven't been able to get that to work either.
Thanks in advance for any help or insight provided.
datepart converts datetimes to dates. Not helpful here.
If you're just displaying this, then you have a few options, particularly for month. You can just change the format of the variable (This changes what's displayed, but not the underlying value; consider this a value label).
When you use this like this (again, it looks like you got most of the way there):
proc sql;
select datevar format=monyy5. from table;
quit;
Just don't include that datepart function call as that's not appropriate unless you have a datetime. (Date=# of days since 1/1/1960, Datetime = # of seconds since 1/1/1960:00:00:00).
That will display it with MONYY5. format, which would be MAY10 for May, 2010. You have some other format options, see the documentation on formats by category for more details.
I can't think of a Week format that matches what you want (there are week formats, like WEEKW., as you clearly found, but I don't know that they do exactly what you want. So, if you want to build one yourself, you can either build a custom picture format, or you can make a string.
Building a custom picture format isn't too hard; see the documentation on Picture formats or google SAS Date Picture Format.
proc format;
picture weekyear (default=8)
low-high = 'W%0U-%Y' (datatype=date) ;
quit;
Now you can use that as a normal format.
To get at the week/etc. to build values, you can also use functions week(), month(), etc., if that's easier.
Since the data was already in a date format, I only needed to drop the DATEPART function that only works with datetime values. So, for month-yr,
"a.fnlz_date as fnlz_mnth format=monyy.,"
gives me the results I'm looking for.
Cheers!
I have a sas data set which has date field which is in the format "04JAN2012" and using format, I am converting it to "2012-01-04" in a separate data step.
The problem arises when I am using a simple where statement in proc SQL which is using a 'where' condition like---- select * from temp where temp.active_date > '2012-01-01'
The error message at this point is "Expression using equals (>) has components that are of different data types."
Please help !
The best way would be to convert your string ('2012-01-01') into a SAS date before doing the filter, eg via macro:
%let date_filter='2012-01-01';
%let mydate=%sysfunc(mdy(
%substr(&date_filter,7,2)
,%substr(&date_filter,10,2)
,%substr(&date_filter,2,4)));
proc sql;
select * from temp where temp.active_date > &mydate;
If you're using FORMAT and not PUT (which converts to character internally), you aren't actually changing anything about the date beyond how it is displayed (and used in some grouping functions). Internally, active_date still is a numeric SAS date.
As such, you simply need to use the correct format of date constant. While you are using PROC SQL, you still are in SAS, which formats date constants differently than SQL Server or Oracle.
'01JAN2012'd is the correct format of date constant for that, so your code should be:
select * from temp where temp.active_date > '01JAN2012'd;
If you are generating this comparison value in some fashion (not writing it into code), you can generate it properly by PUTting (or FORMATting) the value being generated to DATE9. format.