- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
I have checked your post from 1900 to 21000 and it picks them all...so I am not sure of your check?
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
similar with intck
data want;
date='02jan2016'd;
days=intck('days',intnx('year',date,0,'b'), intnx('year',date,0,'e'))+1;
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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;
Suryakiran
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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).
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
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