Oracle CALENDAR_ Functions

Name the quarter, month, or week of a date, find the first and last day of any period, and move dates by whole periods in one call.

Reports constantly need the name of a period (Q1-2026, MAR-2026, week 11), its first and last day, or a date a few periods later. Oracle AI Database 26ai adds a family of CALENDAR_ functions that answer these directly for the Gregorian calendar, so you no longer build them from TRUNC, TO_CHAR, ADD_MONTHS, and LAST_DAY.

Code for This Guide

The main example is in the examples/date-functions folder of the Oracle Database 26ai code repository on GitHub, with its output. It queries NIMBUS, the sample schema of a fictional airline, which you can install with the scripts in the setup/nimbus folder.

It comes from Oracle Database 26ai SQL and PL/SQL Book.

The Family

Syntax:

calendar_year(dtexpr [, fmt [, nlsparam]])   -- and the other members below
FunctionsReturn
CALENDAR_YEAR, _QUARTER, _MONTH, _WEEK, _DAYThe name of the period a date is in, such as Q1-2026
CALENDAR_YEAR_NUMBERThe year as a number
CALENDAR_DAY_OF_WEEK, _OF_MONTH, _OF_QUARTER, _OF_YEARThe day's number within a period
CALENDAR_WEEK_OF_YEAR, CALENDAR_MONTH_OF_QUARTER, _OF_YEAR, CALENDAR_QUARTER_OF_YEARA period's number within a larger period
CALENDAR_YEAR_START_DATE, _QUARTER_, _MONTH_, _WEEK_START_DATE, and the _END_DATE versionsThe first or last day of a period
CALENDAR_ADD_YEARS, _QUARTERS, _MONTHS, _WEEKS, _DAYSThe date moved by a number of periods
CALENDAR_SINCEThe time since a date in words

The period names have their own formats and ignore NLS_DATE_FORMAT; an optional format argument changes them.

Names, Boundaries, and Arithmetic

The first query names the periods of 15 March 2026; the second finds its quarter's start and end, its day and week of the year, and the date two months later.

Example:

select calendar_year(d) as year, calendar_quarter(d) as quarter,
       calendar_month(d) as month, calendar_week(d) as week, calendar_day(d) as day
from   (select date '2026-03-15' as d);

select calendar_quarter_start_date(d) as q_start, calendar_quarter_end_date(d) as q_end,
       calendar_day_of_year(d) as day_of_year, calendar_week_of_year(d) as week_of_year,
       calendar_add_months(d, 2) as plus_2_months
from   (select date '2026-03-15' as d);

Output:

YEAR    QUARTER    MONTH       WEEK        DAY
_______ __________ ___________ ___________ ______________
2026    Q1-2026    MAR-2026    W11-2026    15-MAR-2026

Q_START        Q_END             DAY_OF_YEAR    WEEK_OF_YEAR PLUS_2_MONTHS
______________ ______________ ______________ _______________ ________________
01-JAN-2026    31-MAR-2026                74              11 15-MAY-2026

More Members

Example:

select calendar_month_start_date(d) as month_start,
       calendar_month_end_date(d)   as month_end,
       calendar_week_start_date(d)  as week_start,
       calendar_add_weeks(d, 3)     as plus_3_weeks,
       calendar_quarter_of_year(d)  as quarter_no
from   (select date '2026-03-15' as d);

-- tickets per calendar quarter and month, named by the calendar functions
select calendar_quarter(b.booked_at) as quarter, calendar_month(b.booked_at) as month,
       count(*) as bookings
from   bookings b
group  by all
order  by min(b.booked_at);

Output:

MONTH_START    MONTH_END      WEEK_START     PLUS_3_WEEKS       QUARTER_NO
______________ ______________ ______________ _______________ _____________
01-MAR-2026    31-MAR-2026    12-MAR-2026    05-APR-2026                 1

QUARTER    MONTH          BOOKINGS
__________ ___________ ___________
Q4-2025    OCT-2025              7
Q4-2025    NOV-2025             81
Q4-2025    DEC-2025            164
Q1-2026    JAN-2026            222
Q1-2026    FEB-2026            154
Q1-2026    MAR-2026             72

6 rows selected.

Calendar weeks are counted from 1 January, so they start on that day's weekday: in 2026 a Thursday, which is why the week of 15 March starts on 12 March. The second query groups bookings by the quarter and month names, ready to print in a report, and orders the groups chronologically with min(booked_at).

Things to Know

  • FISCAL_ functions have the same members for a year that starts on another day, and RETAIL_ functions for the 4-5-4 retail calendar.
  • For ISO weeks that start on Monday, use the IW and IYYY format elements of TO_CHAR.
  • Period names sort as text, not chronologically; order by a date or a number column instead.

Related Guides

Conclusion

The CALENDAR_ functions name the year, quarter, month, week, and day a date falls in, return the first and last day of each period, number days and periods within larger ones, and move dates by whole periods. They replace a lot of hand-built date logic in reports.

Get more Vinish.dev tutorials on Google

See my articles more often when you search Google.

Vinish Kapoor
Vinish Kapoor

An Oracle ACE, author of four books on Oracle APEX, SQL and PL/SQL, and Oracle Forms, and a software developer building Oracle database applications since 2001.

guest

0 Comments
Oldest
Newest Most Voted