I am trying to extract a month from a date in SAS, but so far all my new month variables are coming up as missing.
I have attempted to use some combinations of the month() function in SAS, but so far it just comes up as missing. The dates are formatted as follows: 01/31/2017 (MMDDYY10.)
I have tried
month = month(end_date)
Month =catx('/',put(month(end_date),z2
I would like the Month to show up as a number (01) or a 3 letter code (JAN), currently it is just missing (.)
Thanks in advance!
For month() to return a missing value the end_date variable must be numeric and missing. If end_date were a character variable the log would show invalid numeric data.
Use the monname3. format to convert a date value to a $3. character value mon
monthname = put (end_date, monname3.);
Other alternatives are:
keep the date value unchanged and change the format, or
map the date value to the first of the month value and also format that
For example:
end_date_copy = end_date;
format end_date_copy monname3.;
end_date_month = intnx('month', end_date, 0);
format end_date_month monname3.;
What you ultimately do depends on how the mon is to be used downstream in reporting or aggregating.
Related
I have a column which contians date as string but in many formats like - dd/MM/yy, dd/MMM/yyy .. etc etc. And I am using the following code to convert all strings to one specific date format (yyyy-MM-dd) in hive :
select
from_unixtime(unix_timestamp('31/02/2021','dd/MM/yyyy'),'yyyy-MM-dd')
but this gives me 2021-03-03 in HIVE.
Is there any other way to identify such invalid dates and give null.
Assume, you recognized format correctly and it is exactly 'dd/MM/yyyy' and date is invalid one '31/02/2021'.
unix_timestamp function in such case will move date to the next month and there is no way to change it's behavior. But you can check if the date double-converted from original string to timestamp and back to original format is the same. In case it is not the same, then the date is invalid one.
case
-- check double-converted date is the same as original string
when from_unixtime(unix_timestamp(date_col,'dd/MM/yyyy'),'dd/MM/yyyy') = date_col
--convert to yyyy-MM-dd if the date is valid
then from_unixtime(unix_timestamp('31/02/2021','dd/MM/yyyy'),'yyyy-MM-dd')
else null -- null if invalid date
end as date_converted
Column 1 : I have this date-time format in one column = 2018-10-08T04:30:23Z
Column 3 : I extracted date with formula = =LEFT(A11,10) and changed column format to date.
Column 32 : today(). Just to make sure both date columns match
Now when I want to compare both dates
Column 4 : =IF(C11=D11,TRUE(),FALSE())
It does not work. What did I do wrong?
One option using formulas only would be to use Excel's DATE function, which takes three parameters:
=DATE(YEAR, MONTH, DAY)
Use the following formula to extract a date from your timestamp:
=DATE(LEFT(A1,4), MID(A1,6,2), MID(A1,9,2))
This assumes that the timestamp is in cell A1, with the format in your question. Now, comparing this date value against TODAY() should work, if the original timestamp were also from today.
Should be worth trying:
=1*LEFT(A1,10)=TODAY()
May depend upon your configuration. Without format conversion (the 1*) you are trying to compare text (all string functions return Text) with a Number.
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.);
Question: How do I combine YEAR and MONTH data into a single mm/dd/yyyy date without converting from numeric to character types?
I have date data which needs to be read into SAS. It comes in two columns, YEAR and MONTH. The data looks similar to this:
YEAR MONTH
2012 1
2012 1
2013 10
2012 2
2014 7
The data must be stored in mm/dd/yyyy format. For example, YEAR = 2013 and MONTH = 10 corresponds to 10/01/2013.
I have accomplished this via:
if month = 1 then
date = input(compress("01/01/"||year),mmddyy10.);
else if month = 2 then
date = input(compress("02/01/"||year),mmddyy10.);
...
However, the log gives the following note:
NOTE: Numeric values have been converted to character values at the
places given by:
(Line):(Column).
I understand that this is being done because SAS stores dates as numeric values since January 1, 1960. The Compress function returns a character value. Thus, the numeric data is being coerced into a character type.
While the above code sufficiently solves my problem, the note implies that date formatting should not be handled in this way (via type conversion).
Use the mdy() function:
date = mdy(month, 1, year)
I am trying to get the last day of the month from a field numeric in SAS (ccyymm).
for example
201401 would be 31-01-2014.
I have managed to get the field to show as a date type field (still showing as ccyymm though) with the following code in a PROC SQL SELECT statement
year_month_field INFORMAT YYMMN6. AS year_month_date
I think that I found some code from another question that had been asked that should give me the last day of the month once I can get the full date.
INTNX ( MONTH , year_month_date , 1) -1
Will this work? If not any other suggestions would be appreciated.
Dan
Note the difference between how one would convert a yyyymm to "last day of the month"MMMYYYY format below, depending on whether yyyymm is character or numeric variable.
data test;
yyyymm_character='201401';
yyyymm_numeric=201401;
date1=intnx('month', input(yyyymm_character, yymmn6.), 1)-1;
date2=intnx('month', input(put(yyyymm_numeric,6.), yymmn6.), 1)-1;
format date1 date2 date9.;
/*date1=date2=31jan2014*/
run;
Alternatively, you can use the in-built options for intnx functions to automatically set any input date to the last day of the respective month. Use 'e' as shown below.
data test;
yyyymm_character='201401';
yyyymm_numeric=201401;
date1=intnx('month', input(yyyymm_character, yymmn6.), 0, 'e');
date2=intnx('month', input(put(yyyymm_numeric,6.), yymmn6.), 0,'e');
format date1 date2 date9.;
/*date1=date2=31jan2014*/
run