In this post we will deep dive into the world of SAS date interval functions, specifically focusing on
INTNX. These two functions are the linchpins for any SAS programmer looking to master date manipulations.
What is INTNX and INTCK in SAS?
SAS programmers rely on INTNX and INTCK functions to manage date intervals. INTNX shifts a date by a specified interval, while INTCK computes the intervals between two dates. These functions are crucial for prediction, scheduling, trend analysis, and reporting.
- INTCK – The INTCK in SAS is a function that returns the number of time units between two dates. For the time unit, you can choose years, months, weeks, days, and more.
- INTNX – The INTNX function returns a SAS date that is a specified number of time units away from a specified date. For example, you can use the INTNX function to compute the date that is 308 days in the future from a given date.
The INTNX Function in SAS
The INTNX function is SAS is a date-time function that returns a SAS date value by adding a certain number of increments to the initial start date. For example, add one week to today to get the date for next week.
Here’s how to write the syntax for the INTNX function:
INTNX(interval <multiple><.shift-index>, start-from, increment <, 'alignment'>)
For instance, in the code below, we add seven days to Jun 22, 2021.
data intnx_ex; date1='22JUN2021'd; day=intnx('day', date1 , 7); format date1 day date9.; run;
Interval is an interval name. Interval can appear in uppercase or lowercase. The possible values of the interval are listed in the below table.
The type of interval (date, DateTime, or time) must match the type of value in the start date.
The INTNX function returns the SAS numeric date value for the beginning date, time, or DateTime value of the interval you specify in the start–from the argument.
You can use any SAS date format to convert the numeric SAS date.
INTNX function in SAS example
data _null_; day=intnx('day', '01AUG2020'd, 7); week=intnx('week', '01AUG2020'd, 1); tenday=intnx('tenday', '01AUG2020'd, 2); weekday=intnx('weekday', '01AUG2020'd, 2); month_=intnx('month', '01AUG2020'd, 2); semimonth=intnx('semimonth', '01AUG2020'd, 3); qtr=intnx('qtr', '01AUG2020'd, 2); semiyear=intnx('semiyear', '01AUG2020'd, 3); year=intnx('year', '01AUG2020'd, 1); format day week month_ year date9.; put (_all_) (=/); run;
day=08AUG2020 week=02AUG2020 tenday=22148 weekday=22131 month_=01OCT2020 semimonth=22174 qtr=22281 semiyear=22646 year=01JAN2021
Here is the Explanation of the above output:
- day = 08FEB2010 (+7 days from 01AUG2020 is 08AUG2020)
- week = 07FEB2010 ( 01AUG2020 is Saturday so +1 week returns 02AUG2020 which is Sunday)
- tenday = 21AUG2020 (2 times 10-day interval which +20 days from 1st AUG2020)
- weekday = 04AUG2020 (+2 days excluding Saturdays and Sundays)
- month_ = 01APR2010 (+2 month returns 01OCT2020)
- semimonth = 01SEP2020 (+3 semi months, one semi months is from 1st to 15th of a month.)
- qtr = 01JAN2021 (+2 Quarter)
- semiyear = 01JAN2022 (+3 semi years. Jan-Jul is 1 semi year)
- year = 01JAN2011 (+1 year)
How to determine the date that is six weeks from the week of August,1,2020?
data _NULL_; date=intnx('week', '05AUG2020'd, 6); put date date9.; run;
The date returned is the starting date of the week – six weeks from August,5,2020.
INTNX Function in SAS for the beginning of the month
We can calculate the first day of the dates by specifying 0 in the third parameter of the INTNX function.
data intnx_ex; date=today(); firstday=intnx('month', date , 0); format date firstday date9.; run;
INTNX Function in SAS for the end of the month
The day before the following month’s first day is the current month’s last day. Dates in SAS are stored as the number of days since a certain point, so take one away.
data intnx_ex; date=today(); lastday=intnx('month', date ,1)-1; format date lastday date9.; run;
How to align the date within the interval?
In addition to the three arguments, an optional fourth argument can be included. This allows greater control over the exact date returned; the values for the fourth argument are b, e, s, and m and must also be enclosed in quotation marks. The effect of adding these values as the fourth argument is listed below:
- b – The beginning date of the interval is returned (first day of the week/ month/year). This is also the default if nothing is entered.
- e– The date of the end of the interval is returned (last day of the week/ month/year).
- m– The date of the middle of the interval (middle day of the week/ month/year).
- s – The date of the same day within the interval is returned (same day of the week/ month/year).
By default, INTNX and INTCK functions use the number of “calendar boundaries” between the dates, such as the first day of a year, month, or week.
For example, if you choose to measure year intervals, the INTCK function counts how often 01JAN occurred between the dates, and the INTNX function returns a future 01JAN date.
Similarly, if you measure month intervals, the INTCK function counts how many first-of-the-months occur between two dates, and the INTNX function returns a future first-of-the-month date.
data _null_; date=intnx('year', '05AUG2020'd, 5); date_b=intnx('year', '05AUG2020'd, 6, 'b'); date_e=intnx('year', '05AUG2020'd, 6, 'e'); date_m=intnx('year', '05AUG2020'd, 6, 'm'); date_s=intnx('year', '05AUG2020'd, 6, 's'); format date date_b date_e date_m date_s date9.; put (_all_) (=/); run;
date=01JAN2025 date_b=01JAN2026 date_e=31DEC2026 date_m=02JUL2026 date_s=05AUG2026
INTCK in SAS
The INTCK function returns the number of interval boundaries between two dates, times, or DateTime values.
INTCK(interval <multiple> <.shift-index>, start-date, end-date, <'method'>)
- Interval – The interval name and values of the interval can be any of the Date and Time Intervals listed in Table 1 above.
- Multipliers and shift indexes – These options can be used with the basic interval to construct more complex interval specifications.
Find the number of days remaining until Christmas.
data _null_; days=intck('day', today(), '24dec2022'd); put days; run;
What if you want to have the end date dynamically take the Christmas date every year?
You can combine the holiday and year functions with the INTCK to dynamically return the number of days until Christmas every year.
data _null_; days=intck('day', today(), holiday('christmas', year(today()))); put days; run;
Find the number of days to Christmas starting from next weekend
data _null_; next_weekend=intnx('week.7', today(), 1); put next_weekend date9.; days=intck('days', next_weekend, holiday('christmas', year(today()))); put days; run;
This example uses the INTCK, INTNX, year, and today functions. First, INTNX is used to find the date of the next weekend, and then the INTNX and holiday functions are used to calculate the number of days.
Today() is used to return the current year dynamically.
You can combine the above program into a single line of code below.
data _null_; days=intck('days', intnx('week.7', today(), 1), holiday('christmas', year(today()))); put days; run;
Creating your Intervals Using Multipliers and Shifting Intervals
To create complex intervals, you can use multipliers and shift indexes. For example, if you want your year to start on July 1 instead of January 1 (as in a financial year), you can do that using shift intervals.
“YEAR.7” moves the start of the YEAR interval to the seventh month, July 1st, instead of January.
The syntax follows below.
The three parts of the interval name are listed below:
- Interval – It specifies the name of the basic interval type. For example, YEAR specifies yearly intervals. Refer to the Commonly Used Time Intervals.
- Multiple – specifies an optional multiplier that sets the interval equal to a multiple of the period of the basic interval type. For example, the interval YEAR2 consists of two-year, or biennial, periods.
- Shift index is used to shift the interval to start at a specified subperiod starting point. For example, YEAR.7 specifies yearly periods shifted to start on the first of July and end in June of the following year.
Note that the shift index cannot exceed the number of subperiods in the entire interval. For example, you could use YEAR2.24, but YEAR2.25 would be an error because there is no 25th month in a two-year interval.
multiplier and the shift–index arguments are optional and default to 1.
For example, YEAR, YEAR1, YEAR.1, and YEAR1.1 all represent ordinary calendar years that begin in January.
To create a 100 Year interval or a century, you can use YEAR100 as the interval.
Multiplying and shifting intervals.
data _null_; day=intnx('day2', '01AUG2020'd, 2); week=intnx('week1.3', '01AUG2020'd, 1); biweekly=intnx('week2.2', '01AUG2020'd, 1); monthly=intnx('month2.2', '01AUG2020'd, 1); year=intnx('year1.3', '01AUG2020'd, 1); format day week biweekly monthly year date9.; put (_all_) (/) ; run;
05AUG2020 04AUG2020 03AUG2020 01OCT2020 01MAR2021
Here is the Explanation of the above output
- day = 05AUG2020 (+2 days interval twice)
- week = 04AUG2020 (Next Tuesday)
- biweekly – 03AUG2020 (Biweekly intervals starting on the first Monday
- monthly – 01OCT2020 (+2 months starting from February till January of the following year
- year = 01MAR2021 (Next Year’s third month (March) 1st day)
Time intervals that do not nest within years or days are aligned relative to the SAS date or DateTime value 0. SAS uses the arbitrary reference time of midnight on January 1, 1960, as the origin for non-shifted intervals. Shifted intervals are defined relative to January 1, 1960.
For example, MONTH13 defines the intervals January 1, 1960, February 1, 1961, March 1, 1962, and so on, and the intervals December 1, 1958, November 1, 1957, and so on, before the base date January 1, 1960.
As another example, the interval specification WEEK6.13 defines six-week periods starting on second Fridays. The convention of alignment relative to the period that contains January 1, 1960, determines where to start counting to determine which dates correspond to the second Fridays of six-week intervals.
CONTINUOUS and DISCRETE
Both functions support many options to modify the default behavior. For example, to count full-year intervals, instead of the number of times people celebrated Christmas, these functions have options to count the number of “anniversaries” between two dates and compute the date of a future anniversary.
You can use the ‘CONTINUOUS’ option for the INTCK function and the ‘SAME’ option for the INTNX function, as follows:
The ‘CONTINUOUS’ option in the INTCK function enables you to count the number of anniversaries of one date before a second date. For example, the statement.
Years_c = intck('year', '31DEC2020'd, '01JAN2021'd, 'CONTINUOUS'); Years_d = intck('year', '31DEC2020'd, '01JAN2021'd, 'd');
The first statement returns 0 because there are no full years between the two dates. The discrete options return one because 01JAN occurs one time between the two dates.
Leap years are handled automatically in these functions. If you want to find the number of days between two dates, the INTCK function includes leap days in the output.
We hope this article helped you understand the Date functions – INTCK and INTNX in SAS.