MySQL 날짜 및 시간 함수 완전 정리

MySQL은 날짜와 시간 데이터를 다루기 위한 다양한 내장 함수를 제공합니다. 이 글에서는 현재 날짜/시간 획득, 특정 값 추출, 계산, 변환 및 타임스탬프 처리에 이르기까지 주요 함수들을 상세히 살펴봅니다.

1. 현재 날짜 및 시간 정보 가져오기

1.1 NOW() - 현재 날짜 + 시간

NOW()는 가장 일반적으로 사용되는 함수로, 쿼리가 실행되는 순간의 날짜와 시간을 반환합니다.

SELECT NOW(); -- 예: 2024-05-21 14:30:00

다음 함수들은 NOW()와 동일한 결과를 제공합니다:

CURRENT_TIMESTAMP()
CURRENT_TIMESTAMP
LOCALTIME()
LOCALTIME
LOCALTIMESTAMP()
LOCALTIMESTAMP

1.2 SYSDATE() - 실행 시점의 시간

SYSDATE()NOW()와 유사하지만, 함수가 호출되는 시점의 시간을 반환합니다. NOW()는 문장(statement) 실행 시작 시점의 시간을 기준으로 하는 반면, SYSDATE()는 함수가 평가되는 순간의 시간을 가져옵니다.

SELECT SYSDATE();

1.3 CURDATE() - 현재 날짜

현재 시스템 날짜만 필요할 때 사용합니다.

SELECT CURDATE(); -- 예: 2024-05-21
SELECT CURRENT_DATE(); -- 동일
SELECT CURRENT_DATE;  -- 동일

1.4 CURTIME() - 현재 시간

SELECT CURTIME(); -- 예: 14:30:00
SELECT CURRENT_TIME(); -- 동일
SELECT CURRENT_TIME;  -- 동일

1.5 UTC 시간 함수

국제 표준시(UTC) 기준의 시간을 제공합니다. 한국(KST)은 UTC+9입니다.

SELECT UTC_DATE();      -- 예: 2024-05-21
SELECT UTC_TIME();      -- 예: 05:30:00
SELECT UTC_TIMESTAMP(); -- 예: 2024-05-21 05:30:00

2. 날짜/시간 값의 특정 부분 추출

2.1 기본 추출 함수

SET @sample_dt = '2008-09-10 07:15:30.123456';

SELECT DATE(@sample_dt);        -- 2008-09-10
SELECT TIME(@sample_dt);        -- 07:15:30.123456
SELECT YEAR(@sample_dt);        -- 2008
SELECT QUARTER(@sample_dt);     -- 3 (7-9월)
SELECT MONTH(@sample_dt);       -- 9
SELECT WEEK(@sample_dt);        -- 36 (연 기준 주차)
SELECT DAY(@sample_dt);         -- 10
SELECT HOUR(@sample_dt);        -- 7
SELECT MINUTE(@sample_dt);      -- 15
SELECT SECOND(@sample_dt);      -- 30
SELECT MICROSECOND(@sample_dt); -- 123456

2.2 EXTRACT() 함수

EXTRACT()YEAR, MONTH 등 단일 단위뿐 아니라 YEAR_MONTH와 같은 복합 단위도 지원합니다. 복합 단위는 지정된 첫 번째 필드부터 마지막 필드까지의 연속된 값을 반환합니다.

SET @sample_dt = '2008-09-10 07:15:30.123456';

-- 단일 단위 추출
SELECT EXTRACT(YEAR FROM @sample_dt);          -- 2008
SELECT EXTRACT(QUARTER FROM @sample_dt);       -- 3
SELECT EXTRACT(MONTH FROM @sample_dt);         -- 9
SELECT EXTRACT(WEEK FROM @sample_dt);          -- 36
SELECT EXTRACT(DAY FROM @sample_dt);           -- 10
SELECT EXTRACT(HOUR FROM @sample_dt);          -- 7
SELECT EXTRACT(MINUTE FROM @sample_dt);        -- 15
SELECT EXTRACT(SECOND FROM @sample_dt);        -- 30
SELECT EXTRACT(MICROSECOND FROM @sample_dt);   -- 123456

-- 복합 단위 추출 (연속된 값)
SELECT EXTRACT(YEAR_MONTH FROM @sample_dt);         -- 200809
SELECT EXTRACT(DAY_HOUR FROM @sample_dt);           -- 1007
SELECT EXTRACT(DAY_MINUTE FROM @sample_dt);         -- 100715
SELECT EXTRACT(DAY_SECOND FROM @sample_dt);         -- 10071530
SELECT EXTRACT(DAY_MICROSECOND FROM @sample_dt);    -- 10071530123456
SELECT EXTRACT(HOUR_MINUTE FROM @sample_dt);        -- 715
SELECT EXTRACT(HOUR_SECOND FROM @sample_dt);        -- 71530
SELECT EXTRACT(HOUR_MICROSECOND FROM @sample_dt);   -- 71530123456
SELECT EXTRACT(MINUTE_SECOND FROM @sample_dt);      -- 1530
SELECT EXTRACT(MINUTE_MICROSECOND FROM @sample_dt); -- 1530123456
SELECT EXTRACT(SECOND_MICROSECOND FROM @sample_dt); -- 30123456

2.3 주(Week) 및 요일 관련 함수

SET @target_date = '2008-08-08';

-- 일자 기준 위치
SELECT DAYOFWEEK(@target_date);  -- 6 (1=일요일, 2=월요일 ... 7=토요일)
SELECT DAYOFMONTH(@target_date); -- 8
SELECT DAYOFYEAR(@target_date);  -- 221

-- 주차 계산
SELECT WEEK(@target_date);       -- 31 (기본 모드)
SELECT WEEK(@target_date, 3);    -- 32 (월요일 시작 모드)
SELECT WEEKOFYEAR(@target_date); -- 32 (WEEK(@dt, 3)과 동일)

-- 요일 인덱스 (0=월요일 기준)
SELECT WEEKDAY(@target_date);    -- 4 (0=월, 1=화 ... 6=일)

-- 연도 + 주차
SELECT YEARWEEK(@target_date);   -- 200831

-- 요일/월 이름
SELECT DAYNAME(@target_date);    -- Friday
SELECT MONTHNAME(@target_date);  -- August

2.4 LAST_DAY() - 월의 마지막 날짜

SELECT LAST_DAY('2008-02-01'); -- 2008-02-29 (윤년)
SELECT LAST_DAY('2008-08-08'); -- 2008-08-31

3. 날짜 및 시간 연산

3.1 DATE_ADD() - 시간 더하기

SET @current = NOW();

SELECT DATE_ADD(@current, INTERVAL 1 DAY);         -- 1일 후
SELECT DATE_ADD(@current, INTERVAL 1 HOUR);        -- 1시간 후
SELECT DATE_ADD(@current, INTERVAL 1 MINUTE);      -- 1분 후
SELECT DATE_ADD(@current, INTERVAL 1 SECOND);      -- 1초 후
SELECT DATE_ADD(@current, INTERVAL 1 MICROSECOND); -- 1마이크로초 후
SELECT DATE_ADD(@current, INTERVAL 1 WEEK);        -- 1주 후
SELECT DATE_ADD(@current, INTERVAL 1 MONTH);       -- 1개월 후
SELECT DATE_ADD(@current, INTERVAL 1 QUARTER);     -- 1분기 후
SELECT DATE_ADD(@current, INTERVAL 1 YEAR);        -- 1년 후

-- 음수 값을 사용하여 빼기
SELECT DATE_ADD(@current, INTERVAL -1 DAY);        -- 1일 전

복합 시간 단위(예: 시:분:초)를 더할 수도 있습니다. ADDDATE()ADDTIME() 대신 DATE_ADD() 사용을 권장합니다.

SET @dt = '2008-08-09 12:12:33';

SELECT DATE_ADD(@dt, INTERVAL '01:15:30' HOUR_SECOND);
-- 결과: 2008-08-09 13:28:03 (1시간 15분 30초 후)

SELECT DATE_ADD(@dt, INTERVAL '1 01:15:30' DAY_SECOND);
-- 결과: 2008-08-10 13:28:03 (1일 1시간 15분 30초 후)

3.2 DATE_SUB() - 시간 빼기

DATE_SUB()DATE_ADD()와 사용법이 완전히 동일하지만 값을 뺍니다. SUBDATE()SUBTIME()보다 DATE_SUB()를 사용하는 것이 좋습니다.

SELECT DATE_SUB(NOW(), INTERVAL 3 DAY); -- 3일 전

3.3 PERIOD_ADD() / PERIOD_DIFF() - 월 단위 연산

인수 P는 'YYYYMM' 또는 'YYMM' 형식이어야 합니다.

SELECT PERIOD_ADD(200808, 2); -- 200810 (2개월 후)
SELECT PERIOD_DIFF(200810, 200808); -- 2 (월 차이)

3.4 DATEDIFF() / TIMEDIFF() - 날짜/시간 차이

SELECT DATEDIFF('2008-08-08', '2008-08-01'); -- 7 (일 수)
SELECT DATEDIFF('2008-08-01', '2008-08-08'); -- -7

SELECT TIMEDIFF('2008-08-08 08:08:08', '2008-08-08 00:00:00'); -- 08:08:08
SELECT TIMEDIFF('08:08:08', '00:00:00'); -- 08:08:08

4. 날짜/시간 형식 변환

4.1 시간과 초 간 변환

SELECT TIME_TO_SEC('01:00:05'); -- 3605
SELECT SEC_TO_TIME(3605);       -- 01:00:05

4.2 날짜와 '0000-00-00' 이후 일수 간 변환

SELECT TO_DAYS('2008-08-08'); -- 733627
SELECT FROM_DAYS(733627);     -- 2008-08-08

4.3 문자열을 날짜/시간으로 변환: STR_TO_DATE()

SELECT STR_TO_DATE('08/09/2008', '%m/%d/%Y');       -- 2008-08-09
SELECT STR_TO_DATE('08/09/08', '%m/%d/%y');         -- 2008-08-09
SELECT STR_TO_DATE('08.09.2008', '%m.%d.%Y');       -- 2008-08-09
SELECT STR_TO_DATE('08:09:30', '%h:%i:%s');         -- 08:09:30
SELECT STR_TO_DATE('08.09.2008 08:09:30', '%m.%d.%Y %h:%i:%s'); -- 2008-08-09 08:09:30

4.4 날짜/시간을 문자열로 변환: DATE_FORMAT() / TIME_FORMAT()

STR_TO_DATE()의 역함수입니다. TIME_FORMAT()은 시간 관련 형식 지정자만 사용해야 합니다.

SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s'); -- 2024-05-21 14:30:00

4.5 지역별 표준 형식 가져오기: GET_FORMAT()

SELECT GET_FORMAT(DATE, 'USA');       -- %m.%d.%Y
SELECT GET_FORMAT(DATE, 'JIS');       -- %Y-%m-%d
SELECT GET_FORMAT(DATE, 'ISO');       -- %Y-%m-%d
SELECT GET_FORMAT(DATE, 'EUR');       -- %d.%m.%Y
SELECT GET_FORMAT(DATE, 'INTERNAL');  -- %Y%m%d

SELECT GET_FORMAT(DATETIME, 'USA');      -- %Y-%m-%d %H.%i.%s
SELECT GET_FORMAT(DATETIME, 'INTERNAL'); -- %Y%m%d%H%i%s

SELECT GET_FORMAT(TIME, 'USA');      -- %h:%i:%s %p
SELECT GET_FORMAT(TIME, 'INTERNAL'); -- %H%i%s

4.6 MAKEDATE() / MAKETIME() - 구성 요소로 날짜/시간 생성

SELECT MAKEDATE(2001, 31);  -- 2001-01-31 (연도 + 31번째 날)
SELECT MAKEDATE(2001, 32);  -- 2001-02-01 (연도 + 32번째 날)
SELECT MAKETIME(12, 15, 30); -- 12:15:30

5. 타임스탬프(TIMESTAMP) 관련 함수

5.1 현재 UNIX 타임스탬프

SELECT UNIX_TIMESTAMP(); -- 예: 1716280200

5.2 UNIX 타임스탬프와 DATETIME 간 변환

SELECT UNIX_TIMESTAMP('2008-08-08 12:00:00'); -- 1218168000
SELECT FROM_UNIXTIME(1218168000);             -- 2008-08-08 12:00:00
SELECT FROM_UNIXTIME(1218168000, '%Y-%m-%d'); -- 2008-08-08

5.3 TIMESTAMP() / TIMESTAMPADD() / TIMESTAMPDIFF()

-- DATE를 TIMESTAMP 값으로 변환
SELECT TIMESTAMP('2008-08-08');          -- 2008-08-08 00:00:00

-- DATETIME에 TIME 더하기
SELECT TIMESTAMP('2008-08-08', '12:00:00'); -- 2008-08-08 12:00:00

-- 시간 간격 더하기/빼기
SELECT TIMESTAMPADD(HOUR, 5, '2008-08-08');        -- 2008-08-08 05:00:00
SELECT TIMESTAMPADD(MONTH, -1, '2008-08-08');      -- 2008-07-08

-- 두 datetime의 차이 (지정된 단위로 반환)
SELECT TIMESTAMPDIFF(DAY, '2008-08-01', '2008-08-08');      -- 7
SELECT TIMESTAMPDIFF(HOUR, '2008-08-08 12:00:00', '2008-08-09 12:00:00'); -- 24

6. 타임존 변환

CONVERT_TZ()를 사용하여 시간대를 변환할 수 있습니다.

SELECT CONVERT_TZ('2008-08-08 12:00:00', '+09:00', '+00:00');
-- 결과: 2008-08-08 03:00:00 (KST -> UTC)

다음과 같은 함수로도 타임존 변환을 구현할 수 있습니다.

SELECT DATE_ADD('2008-08-08 12:00:00', INTERVAL -9 HOUR);            -- 2008-08-08 03:00:00
SELECT DATE_SUB('2008-08-08 12:00:00', INTERVAL 9 HOUR);            -- 2008-08-08 03:00:00
SELECT TIMESTAMPADD(HOUR, -9, '2008-08-08 12:00:00');               -- 2008-08-08 03:00:00

태그: MySQL 날짜함수 시간함수 NOW STR_TO_DATE

6월 4일 20:51에 게시됨