파이썬 datetime·time 모듈 완벽 가이드: 날짜 연산·타임스탬프·타임존

파이썬 datetime과 time 모듈의 차이부터 날짜 계산, 문자열 변환, POSIX 타임스탬프, zoneinfo 타임존 처리와 실행시간 측정까지 예제로 설명합니다.

본문 상단 광고 구역 (승인 후 자동 노출됩니다)
파이썬 datetime time 타임존 처리 가이드
파이썬 날짜·시간 연산과 타임존 완전정리

파이썬에서 날짜와 시간을 다룰 때는 datetime을 중심으로 사용하고, 유닉스 타임스탬프나 실행 대기·성능 측정은 time 모듈을 사용하면 됩니다. 여러 지역의 현지 시간을 변환해야 한다면 단순한 시차 덧셈 대신 표준 라이브러리 zoneinfo로 타임존이 포함된 aware 객체를 만들어야 서머타임까지 안전하게 처리할 수 있습니다.

Python datetime 공식 문서 확인하기

핵심 요약

  • datetime은 날짜 생성·계산·문자열 변환에 적합합니다.
  • time은 POSIX 타임스탬프, 지연, 실행시간 측정에 주로 사용합니다.
  • 서버와 API에서는 UTC로 저장하고 화면에 표시할 때 현지 타임존으로 변환하는 방식이 안전합니다.
  • 타임존 변환에는 Python 3.9 이상 표준 모듈인 zoneinfo를 우선 검토하세요.

datetime과 time 모듈 차이

두 모듈은 이름이 비슷하지만 목적이 다릅니다. 달력상의 날짜를 더하거나 특정 형식으로 출력하는 작업은 datetime이 읽기 쉽습니다. 반면 현재 타임스탬프를 얻거나 잠시 실행을 멈추고 코드 실행시간을 재는 작업은 time이 간단합니다.

작업 권장 기능 예시
현재 날짜와 시간 datetime datetime.now()
날짜 더하기·빼기 timedelta now + timedelta(days=7)
문자열 파싱·출력 strptime·strftime %Y-%m-%d
POSIX 타임스탬프 datetime·time timestamp(), time.time()
현지 타임존 zoneinfo ZoneInfo("Asia/Seoul")
실행시간 측정 time perf_counter()

날짜·시간 생성과 연산

datetime 모듈은 date, time, datetime, timedelta 클래스를 제공합니다. 모듈과 클래스 이름이 같아 헷갈릴 수 있으므로 처음에는 import datetime as dt처럼 별칭을 쓰면 코드 의미가 분명해집니다.

import datetime as dt

today = dt.date.today()
now = dt.datetime.now()
meeting = dt.datetime(2026, 9, 15, 14, 30)
one_week_later = meeting + dt.timedelta(days=7)

print(today)
print(now)
print(one_week_later)

날짜 간 차이는 빼기 연산으로 구합니다. 결과는 timedelta 객체이며 전체 초가 필요할 때는 .seconds가 아니라 .total_seconds()를 사용해야 합니다. .seconds는 하루를 제외한 초 부분만 담기 때문에 며칠에 걸친 간격을 잘못 계산하기 쉽습니다.

start = dt.datetime(2026, 9, 1, 9, 0)
end = dt.datetime(2026, 9, 3, 12, 30)
delta = end - start

print(delta.days)            # 2
print(delta.total_seconds()) # 전체 기간의 초

문자열을 날짜로, 날짜를 문자열로 변환

외부 파일이나 API에서 받은 문자열을 날짜 객체로 바꿀 때는 strptime(), 날짜 객체를 원하는 문구로 출력할 때는 strftime()을 사용합니다. 포맷 문자열과 실제 입력의 순서가 정확히 일치해야 합니다.

from datetime import datetime

text = "2026-09-15 14:30:00"
parsed = datetime.strptime(text, "%Y-%m-%d %H:%M:%S")
formatted = parsed.strftime("%Y년 %m월 %d일 %H:%M")

print(formatted)

ISO 8601 형태라면 fromisoformat()isoformat()도 편리합니다. 다만 외부 API가 끝에 Z를 붙이는지, UTC 오프셋을 포함하는지 확인해야 합니다. 날짜만 있는 값과 타임존까지 포함된 값은 같은 방식으로 비교하면 안 됩니다.

타임스탬프 변환 방법

POSIX 타임스탬프는 일반적으로 1970년 1월 1일 UTC부터 흐른 초를 표현합니다. 사람이 읽는 현지 시간과 달리 절대 시점을 전달하기 편해 로그와 API에서 널리 사용됩니다.

from datetime import datetime, timezone

now_utc = datetime.now(timezone.utc)
stamp = now_utc.timestamp()
restored = datetime.fromtimestamp(stamp, tz=timezone.utc)

print(stamp)
print(restored.isoformat())

datetime.fromtimestamp()tz를 생략하면 시스템의 로컬 타임존을 적용할 수 있습니다. 개발 PC와 서버의 설정이 다르면 결과가 달라지는 원인이 되므로 서버 코드에서는 타임존 인수를 명시하는 편이 안전합니다.

zoneinfo로 타임존 안전하게 처리하기

naive datetime은 타임존 정보가 없는 객체이고, aware datetime은 UTC 오프셋을 판단할 수 있는 타임존 정보를 가진 객체입니다. 서로 다른 지역의 시간을 비교하거나 저장할 때는 aware 객체를 사용해야 시점이 모호해지지 않습니다.

from datetime import datetime, timezone
from zoneinfo import ZoneInfo

seoul = ZoneInfo("Asia/Seoul")
new_york = ZoneInfo("America/New_York")

now_seoul = datetime.now(seoul)
now_utc = now_seoul.astimezone(timezone.utc)
now_new_york = now_seoul.astimezone(new_york)

print(now_seoul.isoformat())
print(now_utc.isoformat())
print(now_new_york.isoformat())

replace(tzinfo=...)는 시계 숫자를 그대로 둔 채 타임존 꼬리표만 붙입니다. 이미 특정 시점을 나타내는 aware 객체를 다른 지역 시간으로 바꿀 때는 astimezone()을 사용해야 합니다. 서머타임 규칙이 있는 지역을 고정된 시차로 계산하면 계절에 따라 한 시간씩 틀릴 수 있습니다.

서버·데이터베이스 권장 흐름

  1. 현재 시각을 UTC aware 객체로 만듭니다.
  2. 데이터베이스에는 UTC 기준 ISO 문자열 또는 명확한 타임스탬프로 저장합니다.
  3. API 응답에는 UTC 표기나 오프셋을 포함합니다.
  4. 사용자에게 보여줄 때만 ZoneInfo로 현지 시각으로 변환합니다.

Windows처럼 IANA 타임존 데이터가 기본 제공되지 않는 환경에서는 Python 공식 문서가 안내하는 tzdata 패키지가 필요할 수 있습니다.

time 모듈: 대기와 실행시간 측정

time.time()은 현재 POSIX 타임스탬프를 실수로 반환합니다. 시스템 시계가 조정될 수 있기 때문에 성능 측정에는 이 값보다 단조 증가 시계를 사용하는 time.perf_counter()가 적합합니다.

import time

start = time.perf_counter()
time.sleep(0.5)
elapsed = time.perf_counter() - start

print(f"실행시간: {elapsed:.3f}초")

sleep()은 해당 스레드의 실행을 최소한 지정 시간 동안 멈춥니다. 정확한 예약 실행 시각을 보장하는 스케줄러가 아니며 운영체제 스케줄링에 따라 더 늦게 다시 실행될 수 있습니다. 주기 작업이라면 APScheduler 같은 스케줄러의 실행 규칙과 함께 사용하는 편이 낫습니다.

날짜·시간 처리 실수 방지 체크리스트

  • 서버 저장값에 UTC인지 현지 시각인지 명확히 표시합니다.
  • naive 객체와 aware 객체를 섞어 비교하지 않습니다.
  • 타임존 변환에는 astimezone()을 사용합니다.
  • 고정 시차로 서머타임 지역을 계산하지 않습니다.
  • 기간의 전체 초는 total_seconds()로 구합니다.
  • 실행시간은 time.time() 대신 perf_counter()로 측정합니다.
  • API 날짜 형식에 오프셋 또는 Z가 포함되는지 확인합니다.
  • 월말에 한 달을 더할 때 30일을 단순히 더하지 않습니다.

자주 묻는 질문

1. datetime.now()와 datetime.utcnow() 중 무엇을 써야 하나요?

타임존이 필요한 서버 코드에서는 datetime.now(timezone.utc)처럼 UTC aware 객체를 만드는 방식이 더 명확합니다.

2. naive datetime이 무엇인가요?

tzinfo가 없어 어느 지역의 시각인지 스스로 판단할 수 없는 날짜·시간 객체입니다.

3. 한국 타임존 이름은 무엇인가요?

zoneinfo.ZoneInfo("Asia/Seoul")을 사용합니다.

4. 타임스탬프는 항상 UTC인가요?

POSIX 타임스탬프는 특정 절대 시점을 나타내지만 이를 문자열로 변환할 때 어떤 타임존을 적용하느냐에 따라 화면의 시각이 달라집니다.

5. 문자열 날짜 비교를 그대로 해도 되나요?

정렬 가능한 동일 ISO 형식이라는 보장이 없다면 먼저 datetime 객체로 파싱해 비교하는 것이 안전합니다.

6. 한 달 뒤 날짜는 timedelta(days=30)으로 구하면 되나요?

월별 일수가 다르므로 정확한 달력 월 연산에는 별도의 월 계산 로직이나 검증된 라이브러리가 필요합니다.

7. time.sleep()은 정확히 지정한 시간만큼 멈추나요?

최소한 지정 시간 동안 중단되며 운영체제 상황에 따라 실제 복귀는 더 늦을 수 있습니다.

8. 실행시간 측정에 time.time()을 쓰면 안 되나요?

가능하지만 시스템 시계 변경 영향을 피하려면 경과시간 측정 전용인 perf_counter()가 더 적합합니다.

9. zoneinfo는 별도 설치가 필요한가요?

Python 3.9부터 표준 라이브러리에 포함되지만 시스템에 IANA 데이터가 없는 환경은 tzdata 패키지가 필요할 수 있습니다.

10. 데이터베이스에는 어떤 형식으로 저장해야 하나요?

UTC 기준임을 명확히 한 ISO 8601 값이나 타임존을 보존하는 데이터베이스 형식을 선택하고, 표시 단계에서 사용자 타임존으로 변환하는 방식이 일반적입니다.

공식 출처와 확인일

본문 하단 광고 구역