데이터베이스에서 현재 날짜와 시간을 조회하는 것은 가장 기본적이면서도 자주 사용되는 기능입니다. 로그 기록, 데이터 입력 시각 확인, 시간 계산 등 다양한 상황에서 필수적이죠. 오늘은 MySQL, PostgreSQL, Oracle, SQL Server 등 주요 데이터베이스별로 날짜/시간을 출력하는 모든 방법을 정리해드립니다.
기본 개념 – 왜 SELECT * FROM NOW()는 안 될까?
여러분이 작성하신 쿼리를 먼저 살펴볼게요:
-- ❌ 잘못된 예시
SELECT * FROM now();
오류 이유:
NOW()는 테이블이 아니라 함수입니다FROM절은 테이블을 지정하는 곳이므로 함수를 직접 사용할 수 없습니다- 날짜/시간 함수는
SELECT절에서 직접 호출해야 합니다
올바른 사용법:
-- ✅ 올바른 예시
SELECT NOW();
-- 또는
SELECT CURRENT_TIMESTAMP;
PostgreSQL – 날짜/시간 함수
PostgreSQL은 가장 다양하고 강력한 날짜/시간 함수를 제공합니다.
기본 함수
-- 현재 날짜와 시간 (타임존 포함)
SELECT NOW();
-- 결과: 2025-10-02 14:30:25.123456+09
-- 현재 날짜와 시간 (표준 SQL)
SELECT CURRENT_TIMESTAMP;
-- 결과: 2025-10-02 14:30:25.123456+09
-- 현재 날짜만
SELECT CURRENT_DATE;
-- 결과: 2025-10-02
-- 현재 시간만
SELECT CURRENT_TIME;
-- 결과: 14:30:25.123456+09
-- 현재 날짜와 시간 (타임존 없음)
SELECT LOCALTIMESTAMP;
-- 결과: 2025-10-02 14:30:25.123456
-- 현재 시간 (타임존 없음)
SELECT LOCALTIME;
-- 결과: 14:30:25.123456
포맷 지정
-- 날짜 포맷 변경
SELECT TO_CHAR(NOW(), 'YYYY-MM-DD');
-- 결과: 2025-10-02
SELECT TO_CHAR(NOW(), 'YYYY년 MM월 DD일');
-- 결과: 2025년 10월 02일
SELECT TO_CHAR(NOW(), 'HH24:MI:SS');
-- 결과: 14:30:25
SELECT TO_CHAR(NOW(), 'YYYY-MM-DD HH24:MI:SS');
-- 결과: 2025-10-02 14:30:25
-- 요일 포함
SELECT TO_CHAR(NOW(), 'YYYY-MM-DD (Day)');
-- 결과: 2025-10-02 (Thursday)
SELECT TO_CHAR(NOW(), 'YYYY-MM-DD (Dy)');
-- 결과: 2025-10-02 (Thu)
날짜 연산
-- 어제
SELECT NOW() - INTERVAL '1 day';
-- 내일
SELECT NOW() + INTERVAL '1 day';
-- 1주일 전
SELECT NOW() - INTERVAL '7 days';
-- 1개월 전
SELECT NOW() - INTERVAL '1 month';
-- 1년 전
SELECT NOW() - INTERVAL '1 year';
-- 3시간 30분 후
SELECT NOW() + INTERVAL '3 hours 30 minutes';
-- 조합 사용
SELECT NOW() + INTERVAL '1 year 2 months 3 days 4 hours 5 minutes';
실전 활용 예제
-- 오늘 등록된 회원 조회
SELECT *
FROM members
WHERE DATE(created_at) = CURRENT_DATE;
-- 최근 7일간 주문 내역
SELECT *
FROM orders
WHERE order_date >= NOW() - INTERVAL '7 days';
-- 이번 달 매출
SELECT SUM(amount)
FROM sales
WHERE DATE_TRUNC('month', sale_date) = DATE_TRUNC('month', NOW());
-- 나이 계산
SELECT
name,
birth_date,
EXTRACT(YEAR FROM AGE(NOW(), birth_date)) AS age
FROM customers;
MySQL / MariaDB – 날짜/시간 함수
MySQL과 MariaDB는 거의 동일한 문법을 사용합니다.
기본 함수
-- 현재 날짜와 시간
SELECT NOW();
-- 결과: 2025-10-02 14:30:25
-- 현재 날짜와 시간 (표준 SQL)
SELECT CURRENT_TIMESTAMP();
-- 또는
SELECT CURRENT_TIMESTAMP;
-- 현재 날짜만
SELECT CURDATE();
-- 또는
SELECT CURRENT_DATE();
-- 결과: 2025-10-02
-- 현재 시간만
SELECT CURTIME();
-- 또는
SELECT CURRENT_TIME();
-- 결과: 14:30:25
-- Unix 타임스탬프
SELECT UNIX_TIMESTAMP();
-- 결과: 1727844625
-- 마이크로초 포함
SELECT NOW(6);
-- 결과: 2025-10-02 14:30:25.123456
포맷 지정
-- DATE_FORMAT 함수 사용
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d');
-- 결과: 2025-10-02
SELECT DATE_FORMAT(NOW(), '%Y년 %m월 %d일');
-- 결과: 2025년 10월 02일
SELECT DATE_FORMAT(NOW(), '%H:%i:%s');
-- 결과: 14:30:25
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');
-- 결과: 2025-10-02 14:30:25
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s %p');
-- 결과: 2025-10-02 02:30:25 PM
-- 요일 포함
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d (%W)');
-- 결과: 2025-10-02 (Thursday)
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d (%a)');
-- 결과: 2025-10-02 (Thu)
주요 포맷 코드:
| 코드 | 설명 | 예시 |
|---|---|---|
| %Y | 4자리 연도 | 2025 |
| %y | 2자리 연도 | 25 |
| %m | 2자리 월 (01-12) | 10 |
| %c | 월 (1-12) | 10 |
| %d | 2자리 일 (01-31) | 02 |
| %e | 일 (1-31) | 2 |
| %H | 24시간 형식 시 (00-23) | 14 |
| %h | 12시간 형식 시 (01-12) | 02 |
| %i | 분 (00-59) | 30 |
| %s | 초 (00-59) | 25 |
| %p | AM/PM | PM |
| %W | 요일 전체명 | Thursday |
| %a | 요일 약어 | Thu |
날짜 연산
-- 어제
SELECT DATE_SUB(NOW(), INTERVAL 1 DAY);
-- 또는
SELECT NOW() - INTERVAL 1 DAY;
-- 내일
SELECT DATE_ADD(NOW(), INTERVAL 1 DAY);
-- 또는
SELECT NOW() + INTERVAL 1 DAY;
-- 1주일 전
SELECT NOW() - INTERVAL 7 DAY;
-- 1개월 전
SELECT NOW() - INTERVAL 1 MONTH;
-- 1년 전
SELECT NOW() - INTERVAL 1 YEAR;
-- 3시간 30분 후
SELECT NOW() + INTERVAL 3 HOUR + INTERVAL 30 MINUTE;
-- 또는
SELECT DATE_ADD(DATE_ADD(NOW(), INTERVAL 3 HOUR), INTERVAL 30 MINUTE);
날짜 부분 추출
-- 연도 추출
SELECT YEAR(NOW());
-- 결과: 2025
-- 월 추출
SELECT MONTH(NOW());
-- 결과: 10
-- 일 추출
SELECT DAY(NOW());
-- 결과: 2
-- 시간 추출
SELECT HOUR(NOW());
-- 결과: 14
-- 분 추출
SELECT MINUTE(NOW());
-- 결과: 30
-- 초 추출
SELECT SECOND(NOW());
-- 결과: 25
-- 요일 (1=일요일, 7=토요일)
SELECT DAYOFWEEK(NOW());
-- 요일 (0=월요일, 6=일요일)
SELECT WEEKDAY(NOW());
-- 요일 이름
SELECT DAYNAME(NOW());
-- 결과: Thursday
실전 활용 예제
-- 오늘 등록된 데이터
SELECT *
FROM users
WHERE DATE(created_at) = CURDATE();
-- 최근 30일간 데이터
SELECT *
FROM orders
WHERE order_date >= DATE_SUB(NOW(), INTERVAL 30 DAY);
-- 이번 주 월요일부터 오늘까지
SELECT *
FROM sales
WHERE sale_date >= DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY);
-- 나이 계산
SELECT
name,
birth_date,
TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) AS age
FROM customers;
-- 두 날짜 차이 (일)
SELECT DATEDIFF(NOW(), '2025-01-01') AS days_passed;
-- 결과: 274
Oracle – 날짜/시간 함수
Oracle은 고유한 날짜/시간 처리 방식을 사용합니다.
기본 함수
-- 현재 날짜와 시간
SELECT SYSDATE FROM DUAL;
-- 결과: 2025-10-02 14:30:25
-- 현재 타임스탬프 (타임존 포함)
SELECT SYSTIMESTAMP FROM DUAL;
-- 결과: 02-OCT-25 02.30.25.123456 PM +09:00
-- 현재 날짜 (표준 SQL)
SELECT CURRENT_DATE FROM DUAL;
-- 현재 타임스탬프 (표준 SQL)
SELECT CURRENT_TIMESTAMP FROM DUAL;
참고: Oracle에서는 FROM DUAL을 반드시 사용해야 합니다. DUAL은 더미 테이블입니다.
포맷 지정
-- TO_CHAR 함수 사용
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD') FROM DUAL;
-- 결과: 2025-10-02
SELECT TO_CHAR(SYSDATE, 'YYYY"년" MM"월" DD"일"') FROM DUAL;
-- 결과: 2025년 10월 02일
SELECT TO_CHAR(SYSDATE, 'HH24:MI:SS') FROM DUAL;
-- 결과: 14:30:25
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') FROM DUAL;
-- 결과: 2025-10-02 14:30:25
-- 요일 포함
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD (DAY)') FROM DUAL;
-- 결과: 2025-10-02 (THURSDAY)
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD (DY)') FROM DUAL;
-- 결과: 2025-10-02 (THU)
날짜 연산
-- 어제
SELECT SYSDATE - 1 FROM DUAL;
-- 내일
SELECT SYSDATE + 1 FROM DUAL;
-- 1주일 전
SELECT SYSDATE - 7 FROM DUAL;
-- 1개월 전
SELECT ADD_MONTHS(SYSDATE, -1) FROM DUAL;
-- 1년 전
SELECT ADD_MONTHS(SYSDATE, -12) FROM DUAL;
-- 3시간 30분 후
SELECT SYSDATE + INTERVAL '3:30' HOUR TO MINUTE FROM DUAL;
-- 다음 달 첫날
SELECT LAST_DAY(SYSDATE) + 1 FROM DUAL;
-- 이번 달 마지막 날
SELECT LAST_DAY(SYSDATE) FROM DUAL;
날짜 부분 추출
-- EXTRACT 함수 사용
SELECT EXTRACT(YEAR FROM SYSDATE) FROM DUAL;
-- 결과: 2025
SELECT EXTRACT(MONTH FROM SYSDATE) FROM DUAL;
-- 결과: 10
SELECT EXTRACT(DAY FROM SYSDATE) FROM DUAL;
-- 결과: 2
-- 요일 (1=일요일, 7=토요일)
SELECT TO_CHAR(SYSDATE, 'D') FROM DUAL;
-- 날짜 차이 계산
SELECT SYSDATE - TO_DATE('2025-01-01', 'YYYY-MM-DD') AS days_diff FROM DUAL;
실전 활용 예제
-- 오늘 등록된 데이터
SELECT *
FROM members
WHERE TRUNC(created_at) = TRUNC(SYSDATE);
-- 최근 30일간 데이터
SELECT *
FROM orders
WHERE order_date >= SYSDATE - 30;
-- 이번 달 데이터
SELECT *
FROM sales
WHERE TRUNC(sale_date, 'MM') = TRUNC(SYSDATE, 'MM');
-- 나이 계산
SELECT
name,
birth_date,
TRUNC(MONTHS_BETWEEN(SYSDATE, birth_date) / 12) AS age
FROM customers;
SQL Server – 날짜/시간 함수
SQL Server는 Microsoft 독자적인 함수들을 제공합니다.
기본 함수
-- 현재 날짜와 시간
SELECT GETDATE();
-- 결과: 2025-10-02 14:30:25.123
-- 고정밀도 현재 시간
SELECT SYSDATETIME();
-- 결과: 2025-10-02 14:30:25.1234567
-- UTC 시간
SELECT GETUTCDATE();
-- 결과: 2025-10-02 05:30:25.123
-- 현재 타임스탬프 (표준 SQL)
SELECT CURRENT_TIMESTAMP;
-- 날짜만 (SQL Server 2012+)
SELECT CAST(GETDATE() AS DATE);
-- 결과: 2025-10-02
-- 시간만 (SQL Server 2012+)
SELECT CAST(GETDATE() AS TIME);
-- 결과: 14:30:25.1230000
포맷 지정
-- FORMAT 함수 (SQL Server 2012+)
SELECT FORMAT(GETDATE(), 'yyyy-MM-dd');
-- 결과: 2025-10-02
SELECT FORMAT(GETDATE(), 'yyyy년 MM월 dd일');
-- 결과: 2025년 10월 02일
SELECT FORMAT(GETDATE(), 'HH:mm:ss');
-- 결과: 14:30:25
SELECT FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm:ss');
-- 결과: 2025-10-02 14:30:25
-- 요일 포함
SELECT FORMAT(GETDATE(), 'yyyy-MM-dd (dddd)');
-- 결과: 2025-10-02 (Thursday)
-- CONVERT 함수 (구버전 호환)
SELECT CONVERT(VARCHAR, GETDATE(), 23);
-- 결과: 2025-10-02 (스타일 코드 23)
SELECT CONVERT(VARCHAR, GETDATE(), 120);
-- 결과: 2025-10-02 14:30:25 (스타일 코드 120)
주요 CONVERT 스타일 코드:
| 코드 | 형식 | 예시 |
|---|---|---|
| 1 | mm/dd/yy | 10/02/25 |
| 23 | yyyy-mm-dd | 2025-10-02 |
| 101 | mm/dd/yyyy | 10/02/2025 |
| 103 | dd/mm/yyyy | 02/10/2025 |
| 111 | yyyy/mm/dd | 2025/10/02 |
| 120 | yyyy-mm-dd hh:mi:ss | 2025-10-02 14:30:25 |
날짜 연산
-- DATEADD 함수 사용
-- 어제
SELECT DATEADD(DAY, -1, GETDATE());
-- 내일
SELECT DATEADD(DAY, 1, GETDATE());
-- 1주일 전
SELECT DATEADD(WEEK, -1, GETDATE());
-- 1개월 전
SELECT DATEADD(MONTH, -1, GETDATE());
-- 1년 전
SELECT DATEADD(YEAR, -1, GETDATE());
-- 3시간 30분 후
SELECT DATEADD(HOUR, 3, DATEADD(MINUTE, 30, GETDATE()));
-- 이번 달 첫날
SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0);
-- 이번 달 마지막 날
SELECT DATEADD(DAY, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) + 1, 0));
날짜 부분 추출
-- DATEPART 함수 사용
SELECT DATEPART(YEAR, GETDATE());
-- 결과: 2025
SELECT DATEPART(MONTH, GETDATE());
-- 결과: 10
SELECT DATEPART(DAY, GETDATE());
-- 결과: 2
SELECT DATEPART(HOUR, GETDATE());
-- 결과: 14
SELECT DATEPART(MINUTE, GETDATE());
-- 결과: 30
SELECT DATEPART(SECOND, GETDATE());
-- 결과: 25
-- 요일 (1=일요일, 7=토요일)
SELECT DATEPART(WEEKDAY, GETDATE());
-- 요일 이름
SELECT DATENAME(WEEKDAY, GETDATE());
-- 결과: Thursday
-- 월 이름
SELECT DATENAME(MONTH, GETDATE());
-- 결과: October
날짜 차이 계산
-- DATEDIFF 함수
-- 일 차이
SELECT DATEDIFF(DAY, '2025-01-01', GETDATE());
-- 결과: 274
-- 월 차이
SELECT DATEDIFF(MONTH, '2024-01-01', GETDATE());
-- 년 차이
SELECT DATEDIFF(YEAR, '2020-01-01', GETDATE());
-- 시간 차이
SELECT DATEDIFF(HOUR, '2025-10-02 10:00:00', GETDATE());
-- 분 차이
SELECT DATEDIFF(MINUTE, '2025-10-02 14:00:00', GETDATE());
실전 활용 예제
-- 오늘 등록된 데이터
SELECT *
FROM users
WHERE CAST(created_at AS DATE) = CAST(GETDATE() AS DATE);
-- 최근 30일간 데이터
SELECT *
FROM orders
WHERE order_date >= DATEADD(DAY, -30, GETDATE());
-- 이번 달 데이터
SELECT *
FROM sales
WHERE YEAR(sale_date) = YEAR(GETDATE())
AND MONTH(sale_date) = MONTH(GETDATE());
-- 나이 계산
SELECT
name,
birth_date,
DATEDIFF(YEAR, birth_date, GETDATE()) AS age
FROM customers;
데이터베이스별 비교표
| 기능 | PostgreSQL | MySQL | Oracle | SQL Server |
|---|---|---|---|---|
| 현재 날짜/시간 | NOW() | NOW() | SYSDATE | GETDATE() |
| 현재 날짜 | CURRENT_DATE | CURDATE() | TRUNC(SYSDATE) | CAST(GETDATE() AS DATE) |
| 현재 시간 | CURRENT_TIME | CURTIME() | – | CAST(GETDATE() AS TIME) |
| 날짜 포맷 | TO_CHAR() | DATE_FORMAT() | TO_CHAR() | FORMAT() / CONVERT() |
| 날짜 더하기 | + INTERVAL | DATE_ADD() / + | + / ADD_MONTHS() | DATEADD() |
| 날짜 빼기 | - INTERVAL | DATE_SUB() / - | - | DATEADD() |
| 날짜 차이 | - 연산자 | DATEDIFF() | - 연산자 | DATEDIFF() |
| 부분 추출 | EXTRACT() | YEAR(), MONTH() 등 | EXTRACT() | DATEPART() |
실무 활용 팁
1. 타임존 처리
-- PostgreSQL
SELECT NOW() AT TIME ZONE 'UTC';
SELECT NOW() AT TIME ZONE 'Asia/Seoul';
-- MySQL (8.0+)
SELECT CONVERT_TZ(NOW(), '+09:00', '+00:00');
-- Oracle
SELECT SYSDATE AT TIME ZONE 'UTC' FROM DUAL;
-- SQL Server
SELECT GETUTCDATE();
SELECT SWITCHOFFSET(SYSDATETIMEOFFSET(), '+00:00');
2. 날짜 유효성 검사
-- PostgreSQL
SELECT '2025-13-01'::DATE; -- 오류 발생
-- MySQL
SELECT STR_TO_DATE('2025-13-01', '%Y-%m-%d'); -- NULL 반환
-- Oracle
SELECT TO_DATE('2025-13-01', 'YYYY-MM-DD') FROM DUAL; -- 오류 발생
-- SQL Server
SELECT TRY_CONVERT(DATE, '2025-13-01'); -- NULL 반환
3. 성능 최적화
-- 나쁜 예: 함수 사용으로 인덱스 사용 불가
SELECT * FROM orders
WHERE DATE(order_date) = '2025-10-02';
-- 좋은 예: 범위 조건으로 인덱스 활용
SELECT * FROM orders
WHERE order_date >= '2025-10-02'
AND order_date < '2025-10-03';
4. NULL 처리
-- PostgreSQL
SELECT COALESCE(last_login, NOW()) FROM users;
-- MySQL
SELECT IFNULL(last_login, NOW()) FROM users;
-- Oracle
SELECT NVL(last_login, SYSDATE) FROM users;
-- SQL Server
SELECT ISNULL(last_login, GETDATE()) FROM users;
종합 예제 – 실무 쿼리
일일 통계 리포트
-- PostgreSQL
SELECT
CURRENT_DATE AS report_date,
COUNT(*) AS total_orders,
SUM(amount) AS total_sales,
AVG(amount) AS avg_sales
FROM orders
WHERE DATE(order_date) = CURRENT_DATE;
-- MySQL
SELECT
CURDATE() AS report_date,
COUNT(*) AS total_orders,
SUM(amount) AS total_sales,
AVG(amount) AS avg_sales
FROM orders
WHERE DATE(order_date) = CURDATE();
-- Oracle
SELECT
TRUNC(SYSDATE) AS report_date,
COUNT(*) AS total_orders,
SUM(amount) AS total_sales,
AVG(amount) AS avg_sales
FROM orders
WHERE TRUNC(order_date) = TRUNC(SYSDATE);
-- SQL Server
SELECT
CAST(GETDATE() AS DATE) AS report_date,
COUNT(*) AS total_orders,
SUM(amount) AS total_sales,
AVG(amount) AS avg_sales
FROM orders
WHERE CAST(order_date AS DATE) = CAST(GETDATE() AS DATE);
기간별 데이터 집계
-- 최근 7일간 일별 집계 (PostgreSQL)
SELECT
DATE(order_date) AS order_day,
COUNT(*) AS order_count,
SUM(amount) AS daily_sales
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '7 days'
GROUP BY DATE(order_date)
ORDER BY order_day DESC;
-- 최근 12개월 월별 집계 (MySQL)
SELECT
DATE_FORMAT(order_date, '%Y-%m') AS order_month,
COUNT(*) AS order_count,
SUM(amount) AS monthly_sales
FROM orders
WHERE order_date >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)
GROUP BY DATE_FORMAT(order_date, '%Y-%m')
ORDER BY order_month DESC;
마무리 – 핵심 정리
데이터베이스별 현재 날짜/시간 조회:
-- PostgreSQL
SELECT NOW();
-- MySQL / MariaDB
SELECT NOW();
-- Oracle
SELECT SYSDATE FROM DUAL;
-- SQL Server
SELECT GETDATE();
기억할 핵심 포인트:
- 날짜/시간 함수는
SELECT절에서 직접 호출 FROM절은 테이블 지정용, 함수는 사용 불가- 각 데이터베이스마다 고유한 함수와 문법 존재
- 포맷 변환 시 각 DB의 전용 함수 활용
- 성능을 위해 날짜 컬럼에 함수 사용 최소화
실무 권장사항:
- 표준 SQL 함수 우선 사용 (
CURRENT_TIMESTAMP,CURRENT_DATE) - 타임존 명시적 처리
- 인덱스 활용을 위한 범위 조건 사용
- 날짜 유효성 검사 로직 포함
여러분은 어떤 데이터베이스를 주로 사용하시나요? 날짜/시간 처리 관련 유용한 팁이 있다면 댓글로 공유해주세요!
참고 자료: