9. Date Manipulation
Determining Whether a Year Is a Leap Year
We want to determine whether the current year is a leap year.
select to_char(
last_day(add_months(trunc(sysdate,'y'),1)),
'DD')
from t1
Determining the Number of Days in a Year
We want to count the number of days in the current year
select add_months(trunc(sysdate,'y'),12) - trunc(sysdate,'y') from dual
Extracting Units of Time from a Date
We want to break the current date down into day, month, year, second, minute, and hour.
select to_number(to_char(sysdate,'hh24')) hour,
to_number(to_char(sysdate,'mi')) min,
to_number(to_char(sysdate,'ss')) sec,
to_number(to_char(sysdate,'dd')) day,
to_number(to_char(sysdate,'mm')) mth,
to_number(to_char(sysdate,'yyyy')) year
from dual

Determining the First and Last Days of a Month
We want to determine the first and last days for the current month
select trunc(sysdate,'mm') firstday,
last_day(sysdate) lastday
from dual
Determining All Dates for a Particular Weekday Throughout a Year
We want to find all the dates in a year that correspond to a given day of the week. For example, generate a list of Fridays for the current year.
with x
as (
select trunc(sysdate,'y')+level-1 dy
from t1
connect by level <=
add_months(trunc(sysdate,'y'),12)-trunc(sysdate,'y')
)
select *
from x
where to_char( dy, 'dy') = 'fri'
Determining the Date of the First and Last Occurrences of a Specific Weekday in a Month
We want the first and last Mondays of the current month as an example.
select
next_day(trunc(sysdate,'mm')-1,'MONDAY') first_monday,
next_day(last_day(trunc(sysdate,'mm'))-7,'MONDAY') last_monday
from dual
Creating a Calendar
We want to create a calendar for the current month.
WITH x AS (
SELECT
*
FROM
(
SELECT
to_char(trunc(sysdate, 'mm') + level - 1,
'iw') wk,
to_char(trunc(sysdate, 'mm') + level - 1,
'dd') dm,
TO_NUMBER(to_char(trunc(sysdate, 'mm') + level - 1,
'd')) dw,
to_char(trunc(sysdate, 'mm') + level - 1,
'mm') curr_mth,
to_char(sysdate, 'mm') mth
FROM
dual
CONNECT BY
level <= 31
)
WHERE
curr_mth = mth
)
SELECT
MAX(
CASE dw
WHEN 2 THEN
dm
END
) mo,
MAX(
CASE dw
WHEN 3 THEN
dm
END
) tu,
MAX(
CASE dw
WHEN 4 THEN
dm
END
) we,
MAX(
CASE dw
WHEN 5 THEN
dm
END
) th,
MAX(
CASE dw
WHEN 6 THEN
dm
END
) fr,
MAX(
CASE dw
WHEN 7 THEN
dm
END
) sa,
MAX(
CASE dw
WHEN 1 THEN
dm
END
) su
FROM
x
GROUP BY
wk
ORDER BY
wk

Listing Quarter Start and End Dates for the Year
We want to return the start and end dates for each of the four quarters of a given year.
select rownum qtr,
add_months(trunc(sysdate,'y'),(rownum-1)*3) q_start,
add_months(trunc(sysdate,'y'),rownum*3)-1 q_end
from emp
where rownum <= 4

Determining Quarter Start and End Dates for a Given Quarter
We want to return the quarter’s start and end dates, for a given year and quarter in the format of YYYYQ (four-digit year, one-digit quarter).
select add_months(q_end,-2) q_start,
last_day(q_end) q_end
from (
select to_date(substr(yrq,1,4)||mod(yrq,10)*3,'yyyymm') q_end
from (
select 20051 yrq from dual union all
select 20052 yrq from dual union all
select 20053 yrq from dual union all
select 20054 yrq from dual
) x
) y

Searching on Specific Units of Time
We want to find all employees hired in February or December, as well as employees hired on a Tuesday.
select ename
from emp
where rtrim(to_char(hiredate,'month')) in ('february','december')
or rtrim(to_char(hiredate,'day')) = 'tuesday'
Comparing Records Using Specific Parts of a Date
We want to find which employees have been hired on the same month and weekday. For example, if an employee was hired on Monday, March 10, 2008, and another employee was hired on Monday, March 2, 2001, we want those two to come up as a match since the day of week and month match.
select a.ename ||
' was hired on the same month and weekday as '||
b.ename as msg
from emp a, emp b
where to_char(a.hiredate,'DMON') = to_char(b.hiredate,'DMON')
and a.empno < b.empno
order by a.ename
Identifying Overlapping Date Ranges
We want to find all instances of an employee starting a new project before ending an existing project.
select a.empno,a.ename,
'project '||b.proj_id||
' overlaps project '||a.proj_id as msg
from emp_project a, emp_project b
where a.empno = b.empno
and b.proj_start >= a.proj_start
and b.proj_start <= a.proj_end
and a.proj_id != b.proj_id
Last updated