날짜와 관련된 유용한 함수들
TO_DATE & TO_TIMESTAMP & TO_CHAR(datetime)
- TO_DATE
{info:title=Syntax}
TO_DATE(CHAR [,FORMAT][,nlsparam])
{info}- TO_DATE는 CHAR, VARCHAR2, NCHAR, NVARCHAR2 타입을 DATE 타입으로 변환한다.
- FORMAT을 생략한다면 CHAR는 Default Date Format과 동일해야 한다.
SQL> SELECT TO_DATE('20110101') AS "Date" FROM DUAL;
SELECT TO_DATE('20110101') AS "Date" FROM DUAL
*
ERROR at line 1:
ORA-01861: literal does not match format string
- NLS_DATE_FORMAT 파라미터에 맞게 데이터 형식 변경
SQL> SHOW PARAMETER NLS_DATE_FORMAT
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
nls_date_format string DD-MON-RR
SQL> SELECT TO_DATE('01-JAN-11') AS "Date" FROM DUAL;
Date
------------
01-JAN-11
SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'yyyymmdd' ;
Session altered.
SQL> SELECT TO_DATE('20110101') AS "Date" FROM DUAL;
Date
--------
20110101
- 사용 예제 : 기본 형태 TO_DATE 조회하기
SELECT TO_DATE('20110101') AS "Date" FROM DUAL
UNION ALL
SELECT TO_DATE('01/JAN/2011','dd/mon/yyyy') FROM DUAL
UNION ALL
SELECT TO_DATE('2011-01-01','yyyy-mm-dd') FROM DUAL
UNION ALL
SELECT TO_DATE('20110101','yyyymmdd') FROM DUAL
UNION ALL
SELECT TO_DATE('01012011','ddmmyyyy') FROM DUAL
UNION ALL
SELECT TO_DATE('01012011','mmddyyyy') FROM DUAL
UNION ALL
SELECT TO_DATE('01012011','mmddrrrr') FROM DUAL
UNION ALL
SELECT TO_DATE('20110101','yyyymmdd hh24:mi:ss') FROM DUAL;
Date
--------
20110101
20110101
20110101
20110101
20110101
20110101
20110101
20110101
- 사용 예제 : RR(RRRR) Datetime Format 조회하기
{tip:title=RR(RRRR) 유형이란?}
01 ~ 49 = 2001 ~ 2049
50 ~ 99 = 1950 ~ 1999
{tip}
SELECT TO_CHAR(TO_DATE('01-JAN-01', 'DD-MON-RR'), 'YYYY') AS "YEAR" FROM DUAL
UNION ALL
SELECT TO_CHAR(TO_DATE('01-JAN-49', 'DD-MON-RR') ,'YYYY') AS "YEAR" FROM DUAL
UNION ALL
SELECT TO_CHAR(TO_DATE('01-JAN-50', 'DD-MON-RR') ,'YYYY') AS "YEAR" FROM DUAL
UNION ALL
SELECT TO_CHAR(TO_DATE('01-JAN-99', 'DD-MON-RR') ,'YYYY') AS "YEAR" FROM DUAL
UNION ALL
SELECT TO_CHAR(TO_DATE('01-JAN-01', 'DD-MON-RRRR') ,'YYYY') AS "YEAR" FROM DUAL
UNION ALL
SELECT TO_CHAR(TO_DATE('01-JAN-49', 'DD-MON-RRRR') ,'YYYY') AS "YEAR" FROM DUAL
UNION ALL
SELECT TO_CHAR(TO_DATE('01-JAN-50', 'DD-MON-RRRR') ,'YYYY') AS "YEAR" FROM DUAL
UNION ALL
SELECT TO_CHAR(TO_DATE('01-JAN-99', 'DD-MON-RRRR') ,'YYYY') AS "YEAR" FROM DUAL;
YEAR
----
2001
2049
1950
1999
2001
2049
1950
1999
SELECT TO_CHAR(TO_DATE('01-JAN-1945', 'DD-MON-RRRR'), 'YYYY') AS "YEAR" FROM DUAL
UNION ALL
SELECT TO_CHAR(TO_DATE('01-JAN-2099', 'DD-MON-RRRR') ,'YYYY') AS "YEAR" FROM DUAL;
YEAR
----
1945
2099
- TO_TIMESTAMP
{info:title=Syntax}
TO_TIMESTAMP(CHAR [,FORMAT][,nlsparam])
{info}- TO_TIMESTAMP 는 CHAR, VARCHAR2, NCHAR, NVARCHAR2 타입을 TIMESTAMP 타입으로 변환한다.
- FORMAT을 생략한다면 CHAR는 NLS_TIMESTAMP_FORMAT 과 동일해야 한다.
SELECT TO_TIMESTAMP('20110101','yyyymmdd') || ' ---> 하루의 시작' AS "TO_TIMESTAMP" FROM DUAL
UNION ALL
SELECT TO_TIMESTAMP('2011-01-01 00:00:00:000000000','yyyy-mm-dd hh24:mi:ss:ff') || ' ---> 하루의 시작'
FROM DUAL
UNION ALL
SELECT TO_TIMESTAMP('2011-01-01 23:59:59:999999999','yyyy-mm-dd hh24:mi:ss:ff') || ' ---> 하루의 끝'
FROM DUAL;
TO_TIMESTAMP
--------------------------------------------
11/01/01 00:00:00.000000000 ---> 하루의 시작
11/01/01 00:00:00.000000000 ---> 하루의 시작
11/01/01 23:59:59.999999999 ---> 하루의 끝
- TO_CHAR
{info:title=Syntax}
TO_CHAR(DATE TIME [,FORMAT][,nlsparam])
{info}- TO_CHAR(DATETIME)는 DATE, TIMESTAMP, TIMESTAMP WITH TIMEZONE, TIMESTAMP WITH LOCAL TIME ZONE 타입을 VARCHAR2 타입으로 변환한다.
- FORMAT을 생략할 경우 컬럼의 데이터 타입에 따라 다음과 같이 변환된다.
* DATE 데이터는 Default Date Format 으로 변환
* TIMESTAMP, TIMESTAMP WITH LOCAL TIME ZONE 은 Default Timestamp Format 으로 변환
* TIMESTAMP WITH TIME ZONE 은 Default Timestamp with time zone Format 으로 변환
SELECT TO_CHAR(TO_DATE('20110101','yyyymmdd')) AS "Date" FROM DUAL
UNION ALL
SELECT TO_CHAR(TO_DATE('20110101','yyyymmdd'), 'yyyy-mm-dd') FROM DUAL
UNION ALL
SELECT TO_CHAR(TO_DATE('20110101','yyyymmdd'), 'yyyy/mm/dd') FROM DUAL
UNION ALL
SELECT TO_CHAR(TO_DATE('20110101','yyyymmdd'), 'yyyy-mm-dd hh24:mi:ss') FROM DUAL;
Date
-------------------
01-JAN-11
2011-01-01
2011/01/01
2011-01-01 00:00:00
ADD_MONTHS
- ADD_MONTHS
{info:title=Syntax}
ADD_MONTHS(DATE(시작 일자), INTEGER(더할 월))
{info}- ADD_MONTHS 함수는 DATE (시작 일자)에 INTEGER (더할 월)을 계산하여 DATE 형식을 리턴한다.
- INTEGER가 양수이면 시작 일자 이후를, 음수이면 이전 날짜를 추출한다.
- INTEGER는 0을 제외한 정수를 사용해야 정화한 데이터를 얻을 수 있으며, 월을 계산할 때 소수점은 무시된다.
- 사용 예제
SELECT TO_CHAR(ADD_MONTHS(TO_DATE('20110101','yyyymmdd'), 1), 'yyyymmddhh24miss') || ' ---> 20110101,1' AS "ADD_MONTHS"
FROM DUAL
UNION ALL
SELECT TO_CHAR(ADD_MONTHS(TO_DATE('20110101','yyyymmdd'),12),'yyyymmddhh24miss') || ' ---> 20110101,12'
FROM DUAL
UNION ALL
SELECT TO_CHAR(ADD_MONTHS(TO_DATE('20110101','yyyymmdd'),1/24),'yyyymmddhh24miss') || ' ---> 20110101,1/24'
FROM DUAL
UNION ALL
SELECT TO_CHAR(ADD_MONTHS(TO_DATE('20110101','yyyymmdd'),-5),'yyyymmddhh24miss') || ' ---> 20110101,-5'
FROM DUAL
UNION ALL
SELECT TO_CHAR(ADD_MONTHS(TO_DATE('20110101','yyyymmdd'),-5/24),'yyyymmddhh24miss') || ' ---> 20110101,-5/24'
FROM DUAL
UNION ALL
SELECT TO_CHAR(ADD_MONTHS(TO_DATE('20110101','yyyymmdd'),1.9),'yyyymmddhh24miss') || ' ---> 20110101,1.9'
FROM DUAL;
ADD_MONTHS
----------------------------------
20110201000000 ---> 20110101,1
20120101000000 ---> 20110101,12
20110101000000 ---> 20110101,1/24
20100801000000 ---> 20110101,-5
20110101000000 ---> 20110101,-5/24
20110201000000 ---> 20110101,1.9
MONTHS_BETWEEN
- MONTHS_BETWEEN
{info:title=Syntax}
MONTHS_BETWEEN(date1, date2)
{info}- 두 날짜 사이를 월로 계산하여 NUMBER 타입으로 리턴한다.
date1 = date2 => 0
date1 < date2 => < 0
date1 > date2 => > 0
SELECT MONTHS_BETWEEN(TO_DATE('20111001','yyyymmdd'), TO_DATE('20111001','yyyymmdd')) AS "MONTHS_BETWEEN" FROM DUAL
UNION ALL
SELECT MONTHS_BETWEEN(TO_DATE('20111001','yyyymmdd'), TO_DATE('20111201','yyyymmdd'))
FROM DUAL
UNION ALL
SELECT MONTHS_BETWEEN(TO_DATE('20111201','yyyymmdd'), TO_DATE('20111001','yyyymmdd'))
FROM DUAL;
MONTHS_BETWEEN
--------------
0
-2
2
LAST_DAY
- LAST_DAY
{info:title=Syntax}
LIST_DAY(DATE)
{info}- 인자 값에 해당하는 월의 마지막 날을 리턴 (DATE 형식)
- 사용 예제
SELECT TO_CHAR(SYSDATE,'yyyymmdd') AS "LAST_DAY" FROM DUAL
UNION ALL
SELECT TO_CHAR(LAST_DAY(SYSDATE),'yyyymmdd') FROM DUAL;
LAST_DAY
--------
20131108
20131130
NEXT_DAY
- NEXT_DAY
{info:title=Syntax}
NEXT_DAY(DATE , format)
{info}- 인자로 날짜 데이터를 받아 Format(요일) 형식에 맞는 날짜 데이터를 리턴
- 사용 예제
SELECT TO_CHAR(NEXT_DAY(SYSDATE,'Sunday'), 'yyyymmdd hh24:mi:ss') AS "NEXT_DAY" FROM DUAL
UNION ALL
SELECT TO_CHAR(NEXT_DAY(SYSDATE,'Monday'), 'yyyymmdd hh24:mi:ss') FROM DUAL
UNION ALL
SELECT TO_CHAR(NEXT_DAY(SYSDATE,'Tuesday'), 'yyyymmdd hh24:mi:ss') FROM DUAL
UNION ALL
SELECT TO_CHAR(NEXT_DAY(SYSDATE,'Wednesday'), 'yyyymmdd hh24:mi:ss') FROM DUAL
UNION ALL
SELECT TO_CHAR(NEXT_DAY(SYSDATE,'Thursday'), 'yyyymmdd hh24:mi:ss') FROM DUAL
UNION ALL
SELECT TO_CHAR(NEXT_DAY(SYSDATE,'Friday'), 'yyyymmdd hh24:mi:ss') FROM DUAL
UNION ALL
SELECT TO_CHAR(NEXT_DAY(SYSDATE,'Saturday'), 'yyyymmdd hh24:mi:ss') FROM DUAL;
NEXT_DAY
-----------------
20131110 15:58:02
20131111 15:58:02
20131112 15:58:02
20131113 15:58:02
20131114 15:58:02
20131115 15:58:02
20131109 15:58:02
[, format] 은 옵션이 아닌 필수이다.
http://docs.oracle.com/cd/E11882_01/olap.112/e23381/row_functions045.htm#OLAXS438
SQL> SELECT NEXT_DAY(SYSDATE) FROM DUAL;
SELECT NEXT_DAY(SYSDATE) FROM DUAL
*
ERROR at line 1:
ORA-00909: invalid number of arguments
- 참고2 - ORA-01846 오류 발생시 대처방법
SQL> SELECT TO_CHAR(NEXT_DAY(SYSDATE,'Monday'), 'yyyymmdd hh24:mi:ss') FROM DUAL;
SELECT TO_CHAR(NEXT_DAY(SYSDATE,'Monday'), 'yyyymmdd hh24:mi:ss') FROM DUAL
*
Error at line 1
ORA-01846: 지정한 요일이 부적합합니다.
SQL> SELECT TO_CHAR(NEXT_DAY(SYSDATE,'월요일'), 'yyyymmdd hh24:mi:ss') FROM DUAL;
TO_CHAR(NEXT_DAY(SYSDATE,'월요일'),'YYYYMMDDHH24:MI:SS')
-----------------------------------------------------
20131111 17:57:33
SQL> ALTER SESSION SET NLS_DATE_LANGUAGE='AMERICAN';
SQL> SELECT TO_CHAR(NEXT_DAY(SYSDATE,'Monday'), 'yyyymmdd hh24:mi:ss') FROM DUAL;
TO_CHAR(NEXT_DAY(SYSDATE,'MONDAY'),'YYYYMMDDHH24:MI:SS')
--------------------------------------------------------
20131111 17:58:44
ROUND
- ROUND
{info:title=Syntax}
ROUND(DATE , format)
{info}- 날짜 데이터를 Format 형식에 맞게 반올림 한다.
* ROUND(DATE) = 일자 (12시 기준)
* ROUND(DATE, 'YEAR') = 년 (6월 기준)
* ROUND(DATE, 'Q') = 분기 (2번째 월 15일 기준)
* ROUND(DATE, 'MONTH') = 월 (15일 기준)
* ROUND(DATE, 'DD') = 일자 (12시 기준)
* ROUND(DATE, 'HH24') = 시간 (30분 기준)
* ROUND(DATE, 'MI') = 분 (30초 기준)
* ROUND(DATE, 'DAY') = Week가 시작한 일자
SELECT TO_CHAR(SYSDATE, 'yyyymmdd hh24:mi:ss') AS "ROUND( DATE[, format] )"
FROM DUAL
UNION ALL
SELECT TO_CHAR(ROUND(SYSDATE), 'yyyymmdd hh24:mi:ss') FROM DUAL
UNION ALL
SELECT TO_CHAR(ROUND(SYSDATE, 'year'), 'yyyymmdd hh24:mi:ss') || ' ---> ROUND(SYSDATE, ''year'') ' FROM DUAL
UNION ALL
SELECT TO_CHAR(ROUND(SYSDATE, 'q'), 'yyyymmdd hh24:mi:ss') || ' ---> ROUND(SYSDATE, ''q'') ' FROM DUAL
UNION ALL
SELECT TO_CHAR(ROUND(SYSDATE, 'month'), 'yyyymmdd hh24:mi:ss') || ' ---> ROUND(SYSDATE, ''month'') ' FROM DUAL
UNION ALL
SELECT TO_CHAR(ROUND(SYSDATE, 'dd'), 'yyyymmdd hh24:mi:ss') || ' ---> ROUND(SYSDATE, ''dd'') ' FROM DUAL
UNION ALL
SELECT TO_CHAR(ROUND(SYSDATE, 'hh24'), 'yyyymmdd hh24:mi:ss') || ' ---> ROUND(SYSDATE, ''hh24'') ' FROM DUAL
UNION ALL
SELECT TO_CHAR(ROUND(SYSDATE, 'mi'), 'yyyymmdd hh24:mi:ss') || ' ---> ROUND(SYSDATE, ''mi'') ' FROM DUAL
UNION ALL
SELECT TO_CHAR(ROUND(SYSDATE, 'day'), 'yyyymmdd hh24:mi:ss') || ' ---> ROUND(SYSDATE, ''day'') ' FROM DUAL;
ROUND( DATE[, format] )
-----------------------------------------------
20131108 18:16:59
20131109 00:00:00
20140101 00:00:00 ---> ROUND(SYSDATE, 'year')
20131001 00:00:00 ---> ROUND(SYSDATE, 'q')
20131101 00:00:00 ---> ROUND(SYSDATE, 'month')
20131109 00:00:00 ---> ROUND(SYSDATE, 'dd')
20131108 18:00:00 ---> ROUND(SYSDATE, 'hh24')
20131108 18:17:00 ---> ROUND(SYSDATE, 'mi')
20131110 00:00:00 ---> ROUND(SYSDATE, 'day')
TRUNC
- TRUNC
{info:title=Syntax}
TRUNC(DATE , format)
{info}- 날짜 데이터를 Format 형식에 맞게 절삭 한다.
* TRUNC(DATE) = 일자
* TRUNC(DATE, 'YEAR') = 년
* TRUNC(DATE, 'Q') = 분기
* TRUNC(DATE, 'MONTH') = 월
* TRUNC(DATE, 'DD') = 일자
* TRUNC(DATE, 'HH24') = 시간
* TRUNC(DATE, 'MI') = 분
* TRUNC(DATE, 'DAY') = Week가 시작한 일자
SELECT TO_CHAR(SYSDATE, 'yyyymmdd hh24:mi:ss') AS "TRUNC( DATE[, format] )"
FROM DUAL
UNION ALL
SELECT TO_CHAR(TRUNC(SYSDATE), 'yyyymmdd hh24:mi:ss') FROM DUAL
UNION ALL
SELECT TO_CHAR(TRUNC(SYSDATE, 'year'), 'yyyymmdd hh24:mi:ss') || ' ---> TRUNC(SYSDATE, ''year'') ' FROM DUAL
UNION ALL
SELECT TO_CHAR(TRUNC(SYSDATE, 'q'), 'yyyymmdd hh24:mi:ss') || ' ---> TRUNC(SYSDATE, ''q'') ' FROM DUAL
UNION ALL
SELECT TO_CHAR(TRUNC(SYSDATE, 'month'), 'yyyymmdd hh24:mi:ss') || ' ---> TRUNC(SYSDATE, ''month'') ' FROM DUAL
UNION ALL
SELECT TO_CHAR(TRUNC(SYSDATE, 'dd'), 'yyyymmdd hh24:mi:ss') || ' ---> TRUNC(SYSDATE, ''dd'') ' FROM DUAL
UNION ALL
SELECT TO_CHAR(TRUNC(SYSDATE, 'hh24'), 'yyyymmdd hh24:mi:ss') || ' ---> TRUNC(SYSDATE, ''hh24'') ' FROM DUAL
UNION ALL
SELECT TO_CHAR(TRUNC(SYSDATE, 'mi'), 'yyyymmdd hh24:mi:ss') || ' ---> TRUNC(SYSDATE, ''mi'') ' FROM DUAL
UNION ALL
SELECT TO_CHAR(TRUNC(SYSDATE, 'day'), 'yyyymmdd hh24:mi:ss') || ' ---> TRUNC(SYSDATE, ''day'') ' FROM DUAL;
TRUNC( DATE[, format] )
-----------------------------------------------
20131108 18:45:47
20131108 00:00:00
20130101 00:00:00 ---> TRUNC(SYSDATE, 'year')
20131001 00:00:00 ---> TRUNC(SYSDATE, 'q')
20131101 00:00:00 ---> TRUNC(SYSDATE, 'month')
20131108 00:00:00 ---> TRUNC(SYSDATE, 'dd')
20131108 18:00:00 ---> TRUNC(SYSDATE, 'hh24')
20131108 18:45:00 ---> TRUNC(SYSDATE, 'mi')
20131103 00:00:00 ---> TRUNC(SYSDATE, 'day')
- EXTRACT
{info:title=Syntax}
EXTRACT(element FROM datetime)
{info}- DATE나 TIMESTAMP 데이터만 추출할 때 사용된다.
- 사용 가능한 element 목록
|year| month| day| hour| minute| second| timezone_hour| timezone_minute| timezone_region| timezone_abbr|
SELECT TO_CHAR(SYSDATE,'yyyymmdd hh24:mi:ss') AS sysdate_date
, TO_CHAR(systimestamp, 'yyyymmdd hh24:mi:ss') AS systimestamp_date
, EXTRACT (year FROM sysdate) AS ext_year
, EXTRACT (month FROM sysdate) AS ext_month
, EXTRACT (day FROM sysdate) AS ext_day
, EXTRACT (hour FROM systimestamp) AS ext_hour
, EXTRACT (minute FROM systimestamp) AS ext_year
, EXTRACT (second FROM systimestamp) AS ext_second
FROM DUAL;
SYSDATE_DATE SYSTIMESTAMP_DATE EXT_YEAR EXT_MONTH EXT_DAY EXT_HOUR EXT_YEAR EXT_SECOND
----------------- ----------------- ---------- ---------- ---------- ---------- ---------- ----------
20131108 19:13:25 20131108 19:13:25 2013 11 8 10 13 25.705306
SELECT TO_CHAR(TO_DATE('20111025 10:45:55','yyyymmdd hh24:mi:ss'), 'yyyymmdd hh24:mi:ss') AS sysdate_date
, TO_CHAR(TO_TIMESTAMP('20111025 10:45:55','yyyymmdd hh24:mi:ss'), 'yyyymmdd hh24:mi:ss') AS systimestamp_date
, EXTRACT(year FROM TO_DATE('20111025 10:45:55','yyyymmdd hh24:mi:ss')) AS ext_year
, EXTRACT(month FROM TO_DATE('20111025 10:45:55','yyyymmdd hh24:mi:ss')) AS ext_month
, EXTRACT(day FROM TO_DATE('20111025 10:45:55','yyyymmdd hh24:mi:ss')) AS ext_day
, EXTRACT(hour FROM TO_TIMESTAMP('20111025 10:45:55','yyyymmdd hh24:mi:ss')) AS ext_hour
, EXTRACT(minute FROM TO_TIMESTAMP('20111025 10:45:55','yyyymmdd hh24:mi:ss')) AS ext_minute
, EXTRACT(second FROM TO_TIMESTAMP('20111025 10:45:55','yyyymmdd hh24:mi:ss')) AS ext_second
FROM DUAL;
SYSDATE_DATE SYSTIMESTAMP_DATE EXT_YEAR EXT_MONTH EXT_DAY EXT_HOUR EXT_MINUTE EXT_SECOND
----------------- ----------------- ---------- ---------- ---------- ---------- ---------- ----------
20111025 10:45:55 20111025 10:45:55 2011 10 25 10 45 55