- 1 1. MySQL에서 현재 시간 가져오기 (핵심: 가장 짧은 SQL 치트 시트)
- 2 2. MySQL NOW()와 CURRENT_TIMESTAMP의 차이점
- 2.1 2.1 어느 것을 사용해야 할까요? (SELECT 사용 / DEFAULT 사용)
- 2.2 2.2 DEFAULT / ON UPDATE의 올바른 사용법
- 2.3 2.3 NOW()와 SYSDATE()의 차이점 (중요)
- 2.4 2.4 어느 것을 사용해야 할까요?
- 2.5 2.5 일반적인 오해와 문제점
- 2.6 2.6 실용적인 모범 사례
- 2.7 3.1 MySQL datetime 포맷팅: DATE_FORMAT(NOW(), …)
- 2.8 3.2 일본식 또는 12시간 포맷 변환
- 2.9 3.3 MySQL 시간 전용 포맷팅: TIME_FORMAT()
- 2.10 3.4 문자열 → datetime 변환: STR_TO_DATE()
- 2.11 3.5 운영 환경에서의 중요 포인트
- 2.12 3.6 밀리초 단위 포맷팅
- 2.13 3.7 포맷팅 목적별 요약
- 3 4. MySQL 날짜·시간 더하기/빼기 (DATE_ADD / DATE_SUB)
- 4 5. MySQL에서 날짜/시간 차이 계산 (DATEDIFF / TIMESTAMPDIFF)
- 5 6. 현재 시간을 이용한 날짜 범위 쿼리
1. MySQL에서 현재 시간 가져오기 (핵심: 가장 짧은 SQL 치트 시트)
MySQL에서 현재 시간을 가져오려면 기억해야 할 SQL 함수가 몇 개뿐입니다.
아래는 검색 키워드 “MySQL get current time”에 대한 가장 짧은 답변입니다.
1.1 MySQL 현재 날짜와 시간: NOW() / CURRENT_TIMESTAMP
현재 날짜 + 시간 (YYYY-MM-DD HH:MM:SS)을 반환합니다.
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
예시 출력
2025-02-01 15:30:45
NOW()와CURRENT_TIMESTAMP는 보통 동일한 결과를 반환합니다.- 두 함수 모두 현재 날짜와 시간을 반환합니다.
- 밀리초가 필요하면 아래를 사용하세요.
SELECT NOW(3);
주의 사항 (일반적인 실수)
- 서버의 시간대 설정에 따라 달라집니다.
- UTC 환경에서는 일본 시간 대신 UTC가 반환될 수 있습니다.
- 쿼리 실행 중에는 기본적으로 동일한 시간(단일 문장 내에서 고정된 시간)을 반환합니다.
1.2 MySQL 현재 날짜: CURDATE()
날짜만 반환합니다 (시간 없음).
SELECT CURDATE();
예시 출력
2025-02-01
사용 사례
- 오늘의 데이터를 조회
- 날짜 비교 (예: 오늘 기록만 필터링)
주의 사항
- 반환값은
DATE타입입니다. - 시간대 처리(시간이 필요한 경우)에는 적합하지 않습니다.
1.3 MySQL 현재 시간: CURTIME()
시간만 반환합니다.
SELECT CURTIME();
예시 출력
15:30:45
사용 사례
- 영업시간 확인
- 시간 창에 따른 분기 로직
주의 사항
- 날짜 정보가 포함되지 않습니다.
DATE타입 컬럼과 비교할 수 없습니다.
1.4 MySQL 현재 UTC 시간: UTC_TIMESTAMP()
서버 시간대 설정과 관계없이 UTC(협정 세계시) 시간을 반환합니다.
SELECT UTC_TIMESTAMP();
예시 출력
2025-02-01 06:30:45
사용 시점
- 글로벌 서비스
- 로그를 일관되게 UTC로 저장하는 설계
일반적인 실수
NOW()와 혼용하면 시간 오프셋이 발생합니다.- 앱이 JST(일본 표준시)를 가정한다면 9시간 차이가 나타납니다.
1.5 밀리초가 포함된 MySQL 현재 시간: NOW(3) / CURRENT_TIMESTAMP(3)
MySQL 5.6 이후 버전에서는 소수 초를 지원합니다.
SELECT NOW(3);
SELECT CURRENT_TIMESTAMP(3);
예시 출력
2025-02-01 15:30:45.123
저장 시 주의 사항
컬럼도 소수 초를 지원해야 합니다.
DATETIME(3)
TIMESTAMP(3)
지원되지 않는 컬럼에 저장하면 소수 부분이 잘려버립니다.
1.6 목적별 빠른 치트 시트
| Purpose | SQL |
|---|---|
| Current date and time | SELECT NOW(); |
| Get UTC | SELECT UTC_TIMESTAMP(); |
| Date only | SELECT CURDATE(); |
| Time only | SELECT CURTIME(); |
| Get milliseconds | SELECT NOW(3); |
일반적인 함정 요약
- 시간대 확인을 하지 않아 시간 오프셋이 발생함
NOW(3)을 밀리초를 지원하는 컬럼 없이 사용함- UTC와 로컬 시간을 혼용함
- DATETIME과 TIMESTAMP의 차이를 이해하지 못함

MySQL DATETIME과 TIMESTAMP의 차이 (시간대 변환 여부 비교)
2. MySQL NOW()와 CURRENT_TIMESTAMP의 차이점
NOW()와 CURRENT_TIMESTAMP는 비슷해 보이지만, 언제 사용해야 하는지와 동작 방식을 오해하면 쉽게 버그가 발생할 수 있습니다. 여기에서 차이점, 올바른 사용법, 일반적인 함정을 정리합니다.
2.1 어느 것을 사용해야 할까요? (SELECT 사용 / DEFAULT 사용)
■ SELECT에서 현재 날짜/시간을 조회할 때
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
보통 두 함수는 동일한 결과를 반환합니다.
- 동등한 함수(동의어)입니다.
- 반환값은
DATETIME과 동일합니다. - 시간대 설정의 영향을 받습니다.
실용적인 요점
- 가독성을 위해 →
NOW() - 표준 SQL 스타일을 위해 →
CURRENT_TIMESTAMP
■ 컬럼 기본값을 설정할 때
CREATE TABLE logs (
id INT AUTO_INCREMENT PRIMARY KEY,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
여기서 핵심 포인트는:
기본값으로는
CURRENT_TIMESTAMP를 사용하는 것이 일반적입니다.
일부 환경에서는 NOW()도 허용하지만 동작은 MySQL 버전 및 SQL 모드에 따라 다를 수 있습니다. 더 안전한 선택은 CURRENT_TIMESTAMP입니다.
2.2 DEFAULT / ON UPDATE의 올바른 사용법
자동으로 “updated at” 타임스탬프를 업데이트하려면:
CREATE TABLE logs (
id INT AUTO_INCREMENT PRIMARY KEY,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP
);
동작
- INSERT 시 → created_at / updated_at에 현재 시간 설정
- UPDATE 시 → updated_at만 업데이트
일반적인 실수
DATETIME사용 시 소수 초 정밀도가 일치하지 않음- 여러 TIMESTAMP 컬럼 사용 시 오래된 MySQL 제한에 걸림 (MySQL 5.6 및 이전 버전에는 제한이 있었음)
2.3 NOW()와 SYSDATE()의 차이점 (중요)
놓치기 쉬운 점은 SYSDATE()와의 차이입니다.
SELECT NOW(), SYSDATE();
■ 동작 차이
NOW()→ 쿼리 시작 시점에 고정SYSDATE()→ 호출 시점의 시간을 반환
예시:
SELECT NOW(), SLEEP(3), NOW();
NOW()는 동일한 값을 반환합니다.
SELECT SYSDATE(), SLEEP(3), SYSDATE();
SYSDATE()는 3초 차이를 보여줍니다.
2.4 어느 것을 사용해야 할까요?
| Function | Behavior | Recommended use |
|---|---|---|
| NOW() | Fixed within a query | Logging, consistency-focused |
| SYSDATE() | Call-time value | Precise real-time retrieval |
실제 시스템에서 NOW()가 자주 권장되는 이유
- 트랜잭션 내부에서 일관성을 유지 (여러 SQL 문을 함께 처리하는 메커니즘)
- 복제 환경에서 더 안전함
2.5 일반적인 오해와 문제점
❌ “NOW()와 CURRENT_TIMESTAMP는 완전히 동일하므로 신경 쓸 필요가 없습니다.”
→ 환경에 따라 기본값이나 업데이트 동작에서 차이가 나타날 수 있습니다.
❌ “SYSDATE()가 더 정확하므로 항상 더 좋습니다.”
→ 복제 환경에서 문제가 발생할 수 있습니다.
❌ 시간대를 확인하지 않음
SHOW VARIABLES LIKE '%time_zone%';
확인 없이 사용하면 시간 오차가 발생할 수 있습니다.
2.6 실용적인 모범 사례
- SELECT 조회 →
NOW() - 컬럼 기본값 →
CURRENT_TIMESTAMP - 자동 업데이트 →
ON UPDATE CURRENT_TIMESTAMP - 일관성 중시 → 기본값을
NOW()로 설정 - UTC 기반 설계 →
TIMESTAMP+ UTC로 저장
- MySQL 현재 시간 포맷팅 (DATE_FORMAT / TIME_FORMAT)
MySQL에서 현재 시간을 가져온 후, 표시 형식을 변경하는 경우가 매우 흔합니다.
검색 의도 “MySQL current time format”에 가장 중요한 함수는DATE_FORMAT()입니다.
3.1 MySQL datetime 포맷팅: DATE_FORMAT(NOW(), …)
기본 구문:
SELECT DATE_FORMAT(target_datetime, 'format_string');
예시: 현재 시간 포맷팅
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');
예시 출력
2025-02-01 15:30:45
일반적으로 사용되는 포맷 지정자
| 포맷 지정자 | 의미 | 예시 |
|---|---|---|
| %Y | 연도 (4자리) | 2025 |
| %m | 월 (2자리) | 02 |
| %d | 일 (2자리) | 01 |
| %H | 시 (24시간) | 15 |
| %h | 시 (12시간) | 03 |
| %i | 분 | 30 |
| %s | 초 | 45 |
| %p | AM/PM | PM |
3.2 일본식 또는 12시간 포맷 변환
■ 일본식 포맷
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i');
예시 출력:
2025-02-01 15:30
■ 12시간 포맷 + AM/PM
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %h:%i:%s %p');
예시 출력:
2025-02-01 03:30:45 PM
3.3 MySQL 시간 전용 포맷팅: TIME_FORMAT()
TIME 타입 데이터 전용 포맷팅 함수.
SELECT TIME_FORMAT(CURTIME(), '%H:%i');
예시 출력:
15:30
주의
TIME_FORMAT() 은 TIME 타입에만 사용합니다.
DATETIME 에는 DATE_FORMAT() 을 사용하세요.
3.4 문자열 → datetime 변환: STR_TO_DATE()
문자열 데이터를 datetime 타입으로 변환합니다.
SELECT STR_TO_DATE('2025-02-01 15:30:45', '%Y-%m-%d %H:%i:%s');
예시 출력:
2025-02-01 15:30:45
흔한 실수
– 포맷이 맞지 않으면 NULL 반환
– %m 과 %c 를 혼동 (앞에 0을 채우는 월 vs 채우지 않는 월)
3.5 운영 환경에서의 중요 포인트
❌ 포맷팅 후 비교 금지
잘못된 예:
sql
WHERE DATE_FORMAT(created_at, '%Y-%m-%d') = '2025-02-01';
이는 인덱스가 무효화되어(쿼리 성능 저하) 권장되지 않습니다.
권장 방법:
sql
WHERE created_at >= '2025-02-01' AND created_at < '2025-02-02';
❌ DB 측에서 과도하게 포맷팅하지 말 것
웹 애플리케이션에서는 표시용 포맷팅을 애플리케이션 측에서 처리하는 것이 보통 더 유연합니다.
데이터베이스는 “저장 및 계산”에 집중해야 합니다.
3.6 밀리초 단위 포맷팅
SELECT DATE_FORMAT(NOW(3), '%Y-%m-%d %H:%i:%s.%f');
%f 는 마이크로초(6자리)를 나타냅니다.
주의
컬럼이 DATETIME(3) 등으로 정의되지 않은 경우, 소수점 이하 부분이 잘려 나갑니다.
MySQL 5.6 이상에서 지원됩니다.
3.7 포맷팅 목적별 요약
| 목적 | 함수 |
|---|---|
| 표시 형식 변경 | DATE_FORMAT |
| 시간만 포맷팅 | TIME_FORMAT |
| 문자열 → datetime 변환 | STR_TO_DATE |
| 밀리초 표시 | %f |
4. MySQL 날짜·시간 더하기/빼기 (DATE_ADD / DATE_SUB)
현재 시간을 가져올 수 있더라도, “X일 후” 혹은 “X시간 전” 같은 날짜·시간 계산 없이 운영 환경에서 효과적으로 활용할 수 없습니다.
여기서는 DATE_ADD() 와 DATE_SUB() 를 현재 시간과 함께 사용하는 방법을 설명합니다.
4.1 MySQL datetime 더하기: DATE_ADD()
기본 구문:
SELECT DATE_ADD(base_datetime, INTERVAL value unit);
예시: 현재 시점부터 7일 후
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY);
예시: 현재 시점부터 2시간 후
SELECT DATE_ADD(NOW(), INTERVAL 2 HOUR);
일반적으로 사용되는 단위
| 단위 | 의미 |
|---|---|
| SECOND | 초 |
| MINUTE | 분 |
| HOUR | 시 |
| DAY | 일 |
| MONTH | 월 |
| YEAR | 연 |
4.2 MySQL datetime 빼기: DATE_SUB()
기본 구문:
SELECT DATE_SUB(base_datetime, INTERVAL value unit);
예시: 30일 전
SELECT DATE_SUB(NOW(), INTERVAL 30 DAY);
예시: 1시간 전
SELECT DATE_SUB(NOW(), INTERVAL 1 HOUR);
활용 사례
– 만료 여부 확인
– 오래된 로그 삭제
– 최근 데이터 추출
4.3 일반적인 운영 패턴
■ 최근 24시간 데이터 조회
sql
SELECT * FROM logs WHERE created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY);
■ 7일 뒤 마감일 설정
sql
INSERT INTO tasks (deadline) VALUES (DATE_ADD(NOW(), INTERVAL 7 DAY));
4.4 일반적인 실수와 주의사항
❌ 컬럼에 함수를 적용하기
Bad example:
WHERE DATE(created_at) = CURDATE();
이렇게 하면 인덱스가 비활성화됩니다(쿼리 성능 최적화).
Recommended:
WHERE created_at >= CURDATE() AND created_at < DATE_ADD(CURDATE(), INTERVAL 1 DAY);
❌ 시간대 무시
NOW()는 서버 시간대를 기준으로 합니다
UTC로 저장한다면, 기본값으로 UTC_TIMESTAMP()를 사용하세요
Example:
SELECT DATE_ADD(UTC_TIMESTAMP(), INTERVAL 1 DAY);
❌ 월 단위 추가 시 함정
SELECT DATE_ADD('2025-01-31', INTERVAL 1 MONTH);
→ 월말 조정으로 인해 날짜가 변경될 수 있습니다.
(환경에 따라 결과가 2025-02-28이 될 수 있습니다.)
월 단위 계산을 사용하기 전에 사양을 이해하세요.
4.5 밀리초 단위 추가
SELECT DATE_ADD(NOW(3), INTERVAL 500 MILLISECOND);
※ MySQL은 MILLISECOND를 직접 지원하지 않습니다.
마이크로초 단위로 지정하세요:
SELECT DATE_ADD(NOW(3), INTERVAL 500000 MICROSECOND);
4.6 모범 사례
Standardize on NOW() or UTC_TIMESTAMP() as your base
Do not apply functions to columns in the WHERE clause
Understand the behavior of month-based addition
If precision is required, use DATETIME(3) or higher
5. MySQL에서 날짜/시간 차이 계산 (DATEDIFF / TIMESTAMPDIFF)
운영 시스템에서는 현재 시간을 단순히 가져오는 것만으로는 충분하지 않습니다. 보통 경과한 일수나 남은 시간을 계산해야 합니다.
5.1 날짜 차이 계산: DATEDIFF()
DATEDIFF()는 두 날짜 사이의 일수 차이를 계산합니다.
SELECT DATEDIFF('2025-02-10', '2025-02-01');
결과
9
핵심 포인트
- 일수만 차이를 반환합니다
- 시간 부분은 무시됩니다
- 결과가 음수가 될 수 있습니다
예시: 생성 이후 일수 계산
SELECT DATEDIFF(NOW(), created_at)
FROM users;
5.2 단위별 차이 계산: TIMESTAMPDIFF()
TIMESTAMPDIFF()를 사용하면 단위를 지정할 수 있습니다.
SELECT TIMESTAMPDIFF(unit, start_datetime, end_datetime);
예시: 시간 차이
SELECT TIMESTAMPDIFF(HOUR, '2025-02-01 10:00:00', '2025-02-01 15:00:00');
결과
5
일반적인 단위
| Unit | Meaning |
|---|---|
| SECOND | Seconds |
| MINUTE | Minutes |
| HOUR | Hours |
| DAY | Days |
| MONTH | Months |
| YEAR | Years |
예시: 로그인 이후 분 계산
SELECT TIMESTAMPDIFF(MINUTE, login_at, NOW())
FROM users;
5.3 실제 사용 사례
- 세션 타임아웃 검사
- 구독 만료 검사
- 로그에서 경과 시간 계산
- 속도 제한 로직
5.4 일반적인 실수
❌ 정밀한 시간이 필요할 때 DATEDIFF 사용
DATEDIFF()는 시간과 분을 무시합니다.
❌ 인자 순서 뒤바꾸기
순서는 다음과 같습니다:
TIMESTAMPDIFF(unit, start, end)
뒤바꾸면 결과가 음수가 됩니다.
❌ 시간대 무시
UTC와 로컬 시간을 혼용하면 차이가 올바르지 않을 수 있습니다.
5.5 모범 사례
- 시간이 중요한 경우
TIMESTAMPDIFF()를 사용하세요 - 간단한 일수 계산에는
DATEDIFF()를 사용하세요 - 일관된 시간대 사용을 보장하세요
- 분산 시스템에서는 UTC를 표준화하세요
6. 현재 시간을 이용한 날짜 범위 쿼리
가장 흔한 실제 요구사항 중 하나는 다음과 같은 특정 시간 범위 내의 레코드를 조회하는 것입니다:
- 오늘의 레코드
- 최근 7일
- 최근 24시간
- 이번 달
6.1 오늘 레코드 조회 (인덱스 친화적)
SELECT *
FROM logs
WHERE created_at >= CURDATE()
AND created_at < DATE_ADD(CURDATE(), INTERVAL 1 DAY);
왜 올바른지
- 컬럼에 함수가 적용되지 않음
- 인덱스를 그대로 사용할 수 있음
- 효율적인 범위 쿼리
6.2 최근 7일
SELECT *
FROM logs
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY);
6.3 최근 24시간
SELECT *
FROM logs
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY);
6.4 이번 달
SELECT *
FROM logs
WHERE created_at >= DATE_FORMAT(NOW(), '%Y-%m-01')
AND created_at < DATE_ADD(DATE_FORMAT(NOW(), '%Y-%m-01'), INTERVAL 1 MONTH);
프로덕션 시스템에서는 경계를 애플리케이션 측에서 계산하고 매개변수로 전달하는 것이 종종 더 좋습니다.
6.5 일반적인 성능 실수
❌ 인덱스가 있는 컬럼에 함수 적용
WHERE DATE(created_at) = CURDATE();
이는 인덱스 사용을 방지하고 전체 테이블 스캔을 일으킵니다.
❌ BETWEEN을 부주의하게 사용
BETWEEN은 포함 연산이며 1초 오차 문제를 일으킬 수 있습니다.
6.6 모범 사례 요약
- 날짜 필터링 시 항상 범위 조건을 사용하세요
- 인덱스가 있는 컬럼에 함수 적용을 피하세요
- 글로벌 시스템에서는 UTC 저장을 선호하세요
- 시간대 가정에 대해 명확히 명시하세요


