Skip to Main Content
  • Questions
  • Get dates based on Quarter of the year

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question.

Asked: May 01, 2007 - 5:20 pm UTC

Last updated: May 15, 2025 - 1:16 am UTC

Version: 8.1.7

Viewed 10K+ times! This question is

You Asked

Tom,

Is there a way I can find the first day and last day of a given quarter.

In a given year, there are 4 quarters.

If I select first quarter then I should be able to get
the first day and last day of the first quarter

example:

quarter = 1 and year is 2007. expected result is 01/01/2007 - 03/31/2007.
similarly quarter = 2 and year is 2007 then expected result is 04/01/2007 - 06/20/2007.

Thanks in advance.



and Tom said...

ops$tkyte%ORA10GR2> select q,
  2         add_months( dt, (q-1)*3 ),
  3         last_day(add_months( dt, (q-1)*3+2 ) )
  4    from (
  5  select to_date( '01-jan-2007', 'dd-mon-yyyy' ) dt,
  6         rownum q
  7    from all_users
  8   where rownum <= 4
  9         )
 10  /

         Q ADD_MONTH LAST_DAY(
---------- --------- ---------
         1 01-JAN-07 31-MAR-07
         2 01-APR-07 30-JUN-07
         3 01-JUL-07 30-SEP-07
         4 01-OCT-07 31-DEC-07

Rating

  (11 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

A reader, May 02, 2007 - 12:44 pm UTC


A reader, September 02, 2008 - 12:15 pm UTC


Find the quarters start date and end date for a given date or sysdate

Tanmoy Choudhury, January 19, 2009 - 2:45 am UTC

Can be found out by using below method :

select TRUNC(sysdate+1, 'Q'),TRUNC(ADD_MONTHS(sysdate, +3), 'Q')-1 from dual

Correction for the above post

Tanmoy Choudhury, January 19, 2009 - 2:51 am UTC

for statement : select TRUNC(sysdate+1, 'Q'),TRUNC(ADD_MONTHS(sysdate, +3), 'Q')-1 from dual

TRUNC(sysdate+1, 'Q') -- 1st date of quarter (+1 is not required, it will return the wrong first date of quarter if the date becomes last day of a given quarter. So, the statement should be like below :

select TRUNC(sysdate, 'Q'),TRUNC(ADD_MONTHS(sysdate, +3), 'Q')-1 from dual

John

Pradeep John, April 01, 2009 - 11:13 am UTC

Tanmoy,
That was exactly what I was looking, concise and precise code

Regards
John

ignore dayoff

Marco, July 14, 2011 - 3:24 am UTC

this is how do I calculate end of quarter ignoring days off:

with

calendar1 as
(select * from
(select to_date('29.03.2012','DD.MM.YYYY') as arcdate, 0 as dayoff from dual union all
select to_date('30.03.2012','DD.MM.YYYY') as arcdate, 0 as dayoff from dual union all
select to_date('31.03.2012','DD.MM.YYYY') as arcdate, 1 as dayoff from dual)
where dayoff = 0),

end1 as
(select TRUNC(ADD_MONTHS(to_date('25.03.2012','DD.MM.YYYY'), +1), 'Q')-1 as end_of_quarter from dual)

select max(calendar1.arcdate) as end_of_quarter
from calendar1, end1
where calendar1.arcdate <= end1.end_of_quarter


I need to create list of end_of_quarter for period "between sysdate MINUS two years and sysdate PLUS two years". Please note, dayoff is not only Saturday and Sunday, but it's also state holiday, etc. In real life table calendar1 is updated by central bank.

Could you please suggest me some decision?

Marco, July 14, 2011 - 4:48 am UTC

here is decision for ignoring dayoff (table calendar1 should be updated):


with calendar1 as (select *
from (select to_date('29.03.2012','DD.MM.YYYY') as arcdate, 0 as dayoff from dual union all
select to_date('30.03.2012','DD.MM.YYYY') as arcdate, 0 as dayoff from dual union all
select to_date('31.03.2012','DD.MM.YYYY') as arcdate, 1 as dayoff from dual)
where dayoff = 0),
end1 as (select TRUNC(ADD_MONTHS(sysdate, (level - 8)*3), 'Q') start_of_quarter,
ADD_MONTHS(TRUNC(ADD_MONTHS(sysdate, (level - 8)*3), 'Q'), +3)-1 as end_of_quarter
from dual
connect by level <= 16)
select e1.start_of_quarter, nvl(max(c1.arcdate), e1.end_of_quarter) as actual_end_of_quarter
from calendar1 c1,
end1 e1
where c1.arcdate(+) between e1.start_of_quarter
and e1.end_of_quarter
group by e1.start_of_quarter, e1.end_of_quarter

to get Last Quarter and current month

A reader, March 12, 2014 - 11:05 am UTC

SELECT TO_CHAR(TRUNC(SYSDATE,'q')-1,'yyyy')||'-Q'||TO_CHAR(TRUNC(SYSDATE,'q')-1,'Q') AS LAST_QUARTER, TO_CHAR(TRUNC(SYSDATE,'mm'),'MON-yyyy')
CURRENT_MONTH from dual;

READER

SAILAJA, March 21, 2017 - 12:26 pm UTC


First date and last day of a quarter

Alvaro, February 01, 2018 - 8:17 pm UTC

variable v_year    number

variable v_quarter number

exec :v_year     :=2017

exec :v_quarter:=4

select :v_year    as year,
       :v_quarter as quarter,
       to_date(:v_year||to_char(-2+3*:v_quarter,'fm00'),'yyyymm')        as quarter_start,
       last_day(to_date(:v_year||to_char(3*:v_quarter,'fm00')||'01 23:59:59','yyyymmdd hh24:mi:ss')) as quarter_end
from dual a;


YEAR|QUARTER|QUARTER_START      |QUARTER_END        
2017|      4|2017-10-01 00:00:00|2017-12-31 23:59:59

New Version from Tom's Code

Pablo Reyes, May 14, 2025 - 8:54 pm UTC

This calculates for current year based on Tom's code

select level as quarter,
add_months( TRUNC(CURRENT_DATE, 'YYYY'), (level -1) *3 ) "First Day Of Quarter",
last_day(add_months( TRUNC(CURRENT_DATE, 'YYYY'), (level -1) *3 +2 ) ) "Last Day of Quarter"
from dual connect by level <= 4;