If I have a date variable (DATE_UTC), I need to create a variable that has the number of days in the year. Obviously this will be 365 most of the time, but for data normalization I need to know when it is 366 for leap year. This is probably easy, I tried to work from the number of days in a month:
day(intnx('month',t1.DATE_UTC,0,'end'))
But couldn't figure anything out. Is there a way to get the number of days in a year given a date?
Thanks
My preference:
days_in_year = 1 + intnx('year', date_utc, 0, 'end') - intnx('year', date_utc, 0, 'begin');
*********EDITED: Hold off on this one. I'm getting strange results when I test it.
Get the year from the date
Check if last day in February is 28 or 29, if it's 29 it's a leap year and 365 days.
If it's not a leap year it's 366 days.
You can also use the fact that if you take the mod(year, 4) and it's 0 it's a leap year otherwise it's not but there are exceptions to this rules so it depends on how you want to calculate it.
data test;
date='31Jan2020'd;
*check if leap year;
last_day_feb = day(intnx('month', mdy(2, 1, year(date)), 0, 'e'));
if last_day_feb=28 then nDays=365;
else if last_day_feb=29 then nDays=366;
run;
My preference:
days_in_year = 1 + intnx('year', date_utc, 0, 'end') - intnx('year', date_utc, 0, 'begin');
*********EDITED: Hold off on this one. I'm getting strange results when I test it.
Here's a test program, producing inconsistent results. For INTNX, calculation always yields 365. For MDY, it (properly) can calculate either 365 or 366:
data _null_;
do year = 2010 to 2018;
days = 1 + intnx('year', "&sysdate9"d, 0, 'e') - intnx('year', "&sysdate9"d, 0, 'b');
begin = mdy(1, 1, year);
end = mdy(12, 31, year);
diff = end - begin + 1;
put year= days= begin= end= diff=;
end;
run;
I can't explain it!
EDITED: **************************** No problem. I'm just using a constant date in INTNX instead of a date that varies by year. The formula is fine.
Coffee anyone?
I have checked your post from 1900 to 21000 and it picks them all...so I am not sure of your check?
The formula is fine.
The test program is faulty. Instead of using "&sysdate9"d I should have used a value that changes as YEAR changes.
You can also just subtract the beginning of year date from the end of year date. e.g.:
data have;
informat date_utc date9.;
input date_utc;
days_in_year=intnx('year',DATE_UTC,0,'e')-intnx('year',DATE_UTC,0,'b')+1;
cards;
5dec2018
3mar2016
;
Art, CEO, AnalystFinder.com
similar with intck
data want;
date='02jan2016'd;
days=intck('days',intnx('year',date,0,'b'), intnx('year',date,0,'e'))+1;
run;
Using the MOD function on a mathematical condition to find whether it's a leap year or not.
data test ;
date='21AUG2016'D;
If (mod(year(date),4)=0 and mod(year(date),100)^=0) or mod(year(date),400)=0 then Days=366;
else Days=365;
run;
I also like MOD but coupled with the JULDATE function:
daysinyear= mod(juldate(intnx('year',date_utc,0,'e')),1000);
JULDATE returns a value like 18155 (year 2018, 155th day of the year).
That's clever. And if you are doing it in macro code you can use the JULDATE7. format.
%let year=2016 ;
%let days=%substr(%sysfunc(intnx(year,"01JAN&year"d,0,e),juldate7),5);
3724 %put &=year &=days; YEAR=2016 DAYS=366
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.