SAS Date and substracting 1 Month - date

I have a date that is stored as a number that is 201401. I would like to subtract 1 month, so that is 201312 and not 201400.
Also, if there is a more efficient way, please suggest as well. I also have the date stored as 01Jan2014, and would be fine converting the SAS date at that point, so that I can create two new columns (with 1 month subtracted) so that they have the value 01Dec2013 and 201312. Also, a function for incrementing the month forward or backward would be much appreciated.
Thanks in advance.

If you store the date as a SAS date, you can use the function intnx to increment it by whatever period you like.
newdate = intnx('Month',olddate,1,'s');
If you store it as an integer like your original, you're on your own to figure that out. My answer: don't.

The prior answer works.
I just wanted to add, storing as Date in SAS is not the same as storing as integer. It may display 01JAN2014 but it represents a number, so you can still perform computations.
If you store the date as a SAS date, you can use the function intnx to increment it by whatever period you like.
newdate = intnx('Month',olddate,1,'s');

Related

Substract years from a date

I was wondering if someone could help me:
I have a date formatted as ddmmyyP10. From this date I want to substract a certain number of years (yrs). The date is the same for each observation, only yrs changes.
Example for my goal: date = 01.05.2018, yrs=3 -> resulting in 05.2015 (after formatting accordingly)
I have checked for yrdif, datdif and intnx but none of them seems to fit my data.
My (likely naive) first idea was to perform a simple substraction as I understood that sas stores dates internally as sas dates.
When I did
newdate=date-yrs;
format newdate monyy7.;
it showed for each observation May2018, so basically nothing happened.
Thanks in advance for your help!
Best wishes
Use the INTNX() function and proper formatting.
data have;
input date :ddmmyy10.;
format date ddmmyy10.;
datalines;
01.05.2018
;
data want;
set have;
newdate = intnx('Year', date, -3, 's');
format newdate mmyyp8.;
run;
newdate
05.2015

Using Current Date Time in SAS

I am selecting the data from a table using a date string. I would like to select all rows that have a update time stamp greater than or equal to today.
The simplest way that I can think of is to put today's date in the string, and it works fine.
WHERE UPDATE_DTM >'29NOV2016:12:00'DT;
However, if I want to put something like today's date or system date, what should I put?
I used today(), but it returned all rows in the table. I am not sure if it's because today() in SAS refers to the date 1/1/1960? I also tried &sysdate, but it returned an error message seems like it requires a date conversion.
WHERE UPDATE_DTM > TODAY();
Any ideas? Your thoughts are greatly appreciated!
DATETIME() is the datetime equivalent of TODAY() (but includes the current time). You could also use dhms(TODAY(),0,0,0) if you want effectively midnight (or, for your example above, dhms(TODAY(),12,0,0) to get noon today).

SAS dates: format the quarter as year/quarter

I have a data set with SAS date format "01JAN1980". I want to generate a variable called "quarter" with format "1980Q1" or what ever combination of year and quarter.
Here is what I my SAS codes:
quarter=QRT(date)
format quarter yyq.
but it gives me 1960Q1 instead of 1980Q1.
Does any one know where is the problem?
Thanks very much!!!
The Quarter function returns the quarter number, i.e. 1-4. SAS interprets this as a date with a value of 1, which is equivalent to 1st January 1960, then displays that date in yyq. format. So what you actually want here is just to make a copy of the original variable, without changing the value, and apply the format: quarter = date; format quarter yyq.;.
Also, in some cases you might not even need to make a copy of the variable - you can place a format statement in the middle of most procs and it will use that format for the output of the proc.

SAS - Create a month and year date from one integer

I have a data set in which month and year are in one variable and come in the form 200801 which equates to 2008, January. How can I create a SAS date from this integer?
I would like something in the form of Jan 2008 - anything so that SAS recognizes it as a date, as I then need to subtract this value from service date to find out how much time has elapsed since enrollment into the dataset until date of service.
Please also keep in mind that this is a variable, and I have thousands of observations. So I also need the data step/ function to do this for the entire variable.
Any help is appreciated!
You need to put it to a character variable, then input back to numeric. You can do that pretty easily.
date_var = input(put(date_var_orig,6.)||'01',yymmdd8.);
You can also do it this way:
date_var = mdy(mod(date_var_orig,100),1,floor(date_var_orig/100));
Both assume you want the day to equal 1; make a choice there if you want something else (like end of month or middle of month).

Convert date to Unix time without os.time()

I am developing a plugin written in Lua, and I need a way to calculate Unix time or at least a way to compare 2 date strings.
The function I can use only returns date string in the following format
"1/17/2014 6:50 PM"
Is there a way to convert this string to a Unix time?
Unfortunately I don't have access to the OS library so things like os.time() do not work.
Is there any library or something similar that I can work with?
I also thought about splitting the string into parts, but I need a way to add/subtract time
Just compare normalized timestamps:
function normalize(a)
local m,d,y,h,mi,n=a:match("(%d+)/(%d+)/(%d+)%s+(%d+):(%d+)%s+(%w+)")
if n=="PM" then h=h+12 end
return string.format("%04d%02d%02d%02d%02d",y,m,d,h,mi)
end
Date arithmetic is another story. For a complete, pure Lua date library, see luatz or https://github.com/Tieske/date.
If you need to only compare two time, you don't need to get each time's Unix timestamp. One possible solution is to get the time fields from the string like this:
local time = "1/17/2014 6:50 PM"
local month, day, year, hour, minute, am_pm = time:match("(%d+)/(%d+)/(%d+)%s+(%d+):(%d+)%s+(%w+)")
print(month, day, year, hour, minute, am_pm)
Output: 1 17 2014 6 50 PM
Then compare two time from comparing their year, if they are equal, then month, and so on. Remember to use tonumber to compare them by number, not the string itself.