In Stata, how can I change the format of a date from "2010-01-11 00:00:00" to "1/11/2010"? - stata

I am currently trying to change the format of a date from "2010-01-11 00:00:00" to "01-11-2010" or "1/11/2010". Currently "2010-01-11 00:00:00" is in a string format. I have tried to coerce using the date() function but it never returns to the point where Stata can recognize and sort. Would anyone have any idea how to do this?

It's best if for future questions you post attempted code and why it's not working for you.
Maybe this works in your case:
clear all
set more off
*----- example data -----
set obs 1
gen dat = "2010-01-11 00:00:00"
describe
list
*----- what you want -----
gen double dat2 = clock(dat, "YDM hms")
format dat2 %tcDD-NN-YY
describe
list
Note that we go from string type to numeric type (double), and then adjust the display format.
See help format, help datetime and help datetime_display_formats.
Read also:
Stata tip 113: Changing a variable's format: What it does and does not mean
N. J. Cox. 2012.
Stata Journal Volume 12 Number 4.
http://www.stata-journal.com/article.html?article=dm0067

If you are ingesting time data in "2010-01-11 00:00:00" (SQL) format, then by default it is ingested into Stata as a str23
If you would like it as a Stata date format to manipulate, you could try the following (ingested_date_1 ... being your date columns)
foreach sqltime in ingested_date_1 ingested_date_2 {
rename `sqltime' X
generate double `sqltime' = clock(X, "YMD hms")
drop X
format %tcDDmonCCYY_HH:MM:SS `sqltime'
}
This, takes in multiple "dates", just replace your column names with ingested_date_1 ingested_date_2 etc and reformats them and keeps their 'original' name
Now the dates are in a stata recognised time format, %tc based of the clock, this will be sorted in the time-sense like you expect, rather than the ingested string which was not.
Additionally you may now reformat the display of the date to something that you would like or are comfortable reading, although it will make no difference to date manipulation, it is just the displayed appearance, in the case of viewing as "01-11-2010"
as Roberto says
format ingetsed_date_i %tcDD-NN-YY

Related

xline option when date is formatted %th?

I'm doing a connected twoway plot with x-axis as dates formatted as %th with values 2011h1 to 2017h2. I want to put a vertical line at 2016h2 but nothing I've tried has worked.
xline(2016h2)
xline("2016h2")
xline(date==2016h2)
xline(date=="2016h2")
I'm thinking it might be because I formatted dates with
gen date = yh(year, half)
format date %th
I think this is a MWE:
age1820 date
10.42 2011h1
10.33 2011h2
11.66 2012h1
11.01 2012h2
14.29 2013h1
10.95 2013h2
12.42 2014h1
7.04 2014h2
7.07 2015h1
6.95 2015h2
4 2016h1
8.07 2016h2
5.98 2017h1
3.19 2017h2
graph twoway connected age1820 date, xline(2016h2)
Your example will not really work as written without some additional work. I think in future posts you may want to shoot for a fully working example to maximize the chance that you get a good answer quickly. This is why I made up some fake data below.
Try something like this:
clear
set obs 20
gen date = _n + 100
format date %th
gen age = _n*2
display %th 116
display %th 117
tw connected age date, xline(116 `=th(2018h2)') tline(2019h1)
The crux of the matter is that Stata deals with dates as integers that have a special label attached to them by the format command (but not a value label). For example, 0 corresponds to 1960h1. In other words, you need to either:
tell xline() the number that corresponds to the date you want
use th() to figure out what that number is and force the evaluation inside xline().
use tline(), which is smart enough to understand dates.
I think the third is the best option.

SAS: convert date to numeric

I have a column that contains date values. So when imported as numeric, it shows 20668, 20669...etc. if I format it as yymmddn8, it shows 20160802 etc. However, what I really want is a numeric variable that shows 20160802. I have tried to create other to get day, month, year and then concatenate them. Unfortunately, the issue is if month and day is 1 digit, it would only show 201682. what would be the quickest way to achieve my goal. I guess a can turn the day and month variable to text and add 0 if day or month is less than 10. But this is not elegant and efficient. Please help.
Thanks
You can just wrap an input around that format:
data test;
date = 20668;
full_date = input(put(date,yymmddn8.),best12.);
run;
The put is converting the date to character in the format as you want it to appear, and the input with the best12. format is converting it back to numeric in that format.
It sounds like you just need to attach a format to your variable.
format date yymmddn8. ;
Try running this program to see a few of the different formats that are available for displaying dates.
data _null_;
do date = 20668, 20669 ;
put (6*date) (=10. =date9. =yymmddn8. =mmddyy10. =ddmmyy10. =yymmdd10.) ;
end;
run;

Convert SAS numeric dates to datetime format

I am trying to convert a numeric date into date-time format. I am first subtracting a few days from the date I have.
$let from_date = "21JUL2016:00:00:00"dt;
data _null_;
datediff = intnx('dtday',&from_dt,-180);
call symput("cutoff_dt",datediff);
run;
After this I get numeric date like 17633333 which is fine because I am using this numeric date in pass through queries. But I also need to convert this date into datetime format like "21Dec2015:00:00:00"dt so that I can use this date in proc sql as well. So far after searching through sas documents and blogs I have been unable to do this. Help please.
You can use PUT to apply the format, but if you need quotes and the dt then that's a different story. If you do need them, I think that the current macro variable would work as well. Otherwise you have some other issue going on. There is no requirement for SQL to require the formatted value, unless you need a character or you're passing it through to a DB. In those cases the dt won't be required either.
%let from_date = "21JUL2016:00:00:00"dt;
data _null_;
datediff = intnx('dtday',&from_dt,-180);
call symput("cutoff_dt", put(datediff, datetime21.));
run;
SAS stores dates times and datetime values as numbers. Just like in a datastep
where you can write "where x='19feb2016'd" or "where x=20503" which is the number that SAS stores for the date=19feb2016, you can do the same in proc sql.
You only need to write the date value out as a character value if the variable you are comparing to contains the date as a character string. that is y has the value "19feb2016" and x has the value 20503, the test if y=x will not achieve what you want. That is when you have to write if y=put(x,date9.);

Convert two numeric into a date format

I have two numeric variables, year and month. year variable has data such as 2010 and month variable has data such as 1 and 10 (1 through 9 doesn't have zero at the front). I need to combine these two variables and then convert it to YYMMn6. format so that I can merge another dataset based on the date.
For example, the input is:
2012 1
2012 10
The output I want is (in YYMMn6. format):
201201
201210
The codes I tried so far:
year1=close_year;
year2=clse_month;
yearmonth = cats(of year1-year2); *this results in character variable;
DATE2 = INPUT(PUT(yearmonth,8.),YYMMN6.);
FORMAT DATE2 YYMMN6.;
Of course I get an error message. Thanks.
With numeric variables I'd use MDY function rather than putting and whatnot; you're having trouble here because 20101 isn't a valid YYMM value.
dateval = mdy(monthval,1,yearval);
format dateval yymmn6.;
Note that the 'final' date format is wholly unrelated to whatever you use to input the date variable from an informat; there's no difference from SAS's point of view between
dateval = input('01JAN2010',DATE9.);
format dateval YYMMN6.;
and
dateval = input('201001',YYMMN6.);
format dateval YYMMN6.;
The input/informat is converting a value into a numeric number of days since 1/1/1960. The final format is telling SAS how to display that newly created number.
You can use the answer mentioned by Joe which
would give you the flexibility to change to a different format if you want later on,
without any hassle.
would keep the variables in numeric format, so mathematical or
date functions would be easy to apply.
or you can use
mydate=put(mdy(monthval,1,yearval),yymmn6.);
if you want the output in char format.
Both are correct. Choose as per your requiremnt.

How to add hyphen in values in SAS Enterprise Guide (to put in date format)?

I have a table in SAS that has a column of dates but are not in the typical date format (DD-MM-YY). For example, one of them is
21JUN2012:00:00:00
What can I do so that it is in the format
21-Jun-12
? I am using SAS Enterprise Guide so I know I would have to selected Computed Column but I do not know how to go from there. I was thinking of using TRANWRD but I can't seem to get it work.
I would appreciate any help, thanks.
Right-click on the column to be converted and select Properties.
Change the type to Numeric and click Yes in the warning prompt regarding precision.
Change the Group to Date.
Click Informats; the selected value under Categories should be Date.
Change the informat to DDMMYYSw.
Under Attributes, assign an overall width of 10
Click Formats; the selected value under Categories should be Date.
Change the format to DDMMYYSw.
Under Attributes, assign an overall width of 10.
Click OK
If the conversion results are correct in the Preview Results window,
click Commit changes.
Reference
There are many date formats and informats available in SAS to change the date format being presented. A full list of the formats can be found here in the SAS documentation. The format you want is ddmmyyd. and you can just apply the format to the date value (see col1_ example).
For datetime values, you need to use the DATEPART function to extract the date value before applying the format (see col2_ and col3_ examples below).
If your date is provided as text, you need to apply an informat to it to convert it to SAS date value and then you can apply your desired date format to the value using PUT statements. Including converting this value back to text (see col4_ examples below).
data date_infile;
infile datalines delimiter=',';
input col1_date :date9. col2_dtime :datetime18. col3_dtime :datetime18. col4_text $18.;
format col1_date date9. col2_dtime col3_dtime datetime18.;
datalines;
21jun2012,21JUN2012:00:00:00,21JUN2012:12:34:56,21JUN2012:00:00:00
11aug2012,11AUG2012:00:00:00,11AUG2012:01:23:45,11AUG2012:00:00:00
05oct2019,05OCT2019:00:00:00,05OCT2019:01:23:45,05OCT2019:00:00:00
;
run;
data date_results;
set date_infile;
format col1_date col2_date col3_date col4_date ddmmyyd.;
col2_date = datepart(col2_dtime);
col3_date = datepart(col3_dtime);
col4_date = datepart(input(col4_text, datetime18.));
col4_date_as_text = put(put(datepart(input(col4_text, datetime18.)), ddmmyyd.), $8.);
run;