23. 날짜와 시간
date·datetime으로 날짜와 시간을 다룬다.timedelta로 시간 간격을 계산한다.- 날짜와 문자열을 서로 변환한다(
strftime·strptime). - 타임존을 이해하고, 코드의 실행 시간을 측정한다.
먼저: 왜 전용 도구가 필요한가
"3일 뒤는 며칠일까?", "두 날짜 사이는 며칠 차이일까?", "이 코드는 몇 초 걸렸을까?" — 날짜·시간 계산은 의외로 까다롭습니다. 월마다 일수가 다르고, 윤년이 있고, 시간대가 다릅니다. 이를 직접 계산하면 버그투성이가 됩니다.
Python의 datetime 모듈은 이 모든 복잡함을 처리해줍니다. 표준 라이브러리라 설치 없이 바로 씁니다.
from datetime import date, timedelta today = date(2025, 12, 31) next_week = today + timedelta(days=7) print(next_week) # 2026-01-07 (월·연도 넘어가도 정확!)
12월 31일에 7일을 더하면 알아서 1월 7일로 넘어갑니다. 윤년·월말 계산을 우리가 신경 쓸 필요가 없습니다.
datetime 모듈에 맡긴다. 윤년·월말·시간대 같은 복잡함을 정확히 처리해준다.date: 날짜
date는 연·월·일만 다룹니다(시간 없음).
from datetime import date d = date(2025, 12, 31) print(d) # 2025-12-31 print(d.year, d.month, d.day) # 2025 12 31 print(d.weekday()) # 2 (요일: 월=0, 화=1, 수=2 ... 일=6) today = date.today() # 오늘 날짜 print(today)
weekday()는 요일을 숫자로 줍니다(월요일이 0). 수요일이면 2입니다.
datetime: 날짜 + 시간
datetime은 날짜에 시·분·초까지 더합니다.
from datetime import datetime dt = datetime(2025, 12, 31, 14, 30, 0) # 연,월,일,시,분,초 print(dt) # 2025-12-31 14:30:00 print(dt.hour, dt.minute) # 14 30 now = datetime.now() # 현재 날짜+시간 print(now) # 예: 2025-12-31 14:35:22.123456
| 클래스 | 다루는 것 | 예 |
|---|---|---|
date | 날짜만 (연월일) | date(2025, 12, 31) |
datetime | 날짜 + 시간 | datetime(2025, 12, 31, 14, 30) |
time | 시간만 (시분초) | time(14, 30) |
timedelta | 시간 간격 | timedelta(days=7) |
⭐ timedelta: 시간 간격 계산
timedelta는 "기간"을 나타냅니다. 날짜에 더하거나 빼서 미래·과거를 구하고, 두 날짜를 빼서 차이를 구합니다.
from datetime import date, datetime, timedelta today = date(2025, 12, 31) # 더하기/빼기 print(today + timedelta(days=7)) # 2026-01-07 (일주일 후) print(today - timedelta(days=1)) # 2025-12-30 (어제) print(today + timedelta(weeks=2)) # 2026-01-14 (2주 후) # 날짜 차이 (빼면 timedelta가 나옴) diff = date(2026, 1, 15) - date(2025, 12, 31) print(diff.days) # 15 (15일 차이)
timedelta는 days·weeks·hours·minutes·seconds 등으로 만듭니다.
from datetime import datetime, timedelta meeting = datetime(2025, 12, 31, 14, 0) reminder = meeting - timedelta(minutes=30) # 30분 전 알림 print(reminder) # 2025-12-31 13:30:00
timedelta = 다른 날짜. 날짜 − 날짜 = timedelta. 이 두 규칙으로 미래·과거·차이를 모두 계산한다.flowchart LR
D1["날짜 A"]:::data -->|"+ timedelta"| D2["미래 날짜"]:::result
D1 -->|"- timedelta"| D3["과거 날짜"]:::result
D1 -.- Minus["A - B"]:::proc -.->|"= timedelta"| Diff["간격(.days)"]:::result
classDef data fill:#a8dadc,stroke:#457b9d,color:#1d3557
classDef proc fill:#7fd8d8,stroke:#2a9d8f,color:#14532d
classDef result fill:#b8e6c1,stroke:#34a853,color:#14532d
날짜 ↔ 문자열 변환
날짜를 화면에 표시하거나, 사용자 입력·파일의 날짜 문자열을 읽을 때 변환이 필요합니다.
strftime: 날짜 → 문자열 (포맷)
strftime("string format time")은 날짜를 원하는 형식의 문자열로 만듭니다. % 기호로 각 부분을 지정합니다.
from datetime import datetime dt = datetime(2025, 12, 31, 14, 30, 45) print(dt.strftime("%Y-%m-%d")) # 2025-12-31 print(dt.strftime("%H:%M:%S")) # 14:30:45 print(dt.strftime("%Y년 %m월 %d일")) # 2025년 12월 31일 print(dt.strftime("%Y-%m-%d %H:%M")) # 2025-12-31 14:30
| 기호 | 의미 | 예 |
|---|---|---|
%Y | 연도 4자리 | 2025 |
%m | 월 (01~12) | 12 |
%d | 일 (01~31) | 31 |
%H | 시 (00~23) | 14 |
%M | 분 | 30 |
%S | 초 | 45 |
%A | 요일 이름 | Wednesday |
% 형식은 22장 로깅의 datefmt와 똑같습니다. 한 번 익히면 여러 곳에서 씁니다.strptime: 문자열 → 날짜 (파싱)
strptime("string parse time")은 반대로, 날짜 문자열을 datetime 객체로 바꿉니다. 어떤 형식인지 알려줘야 합니다.
from datetime import datetime s = "2025-12-31 14:30" dt = datetime.strptime(s, "%Y-%m-%d %H:%M") # 형식을 명시 print(dt) # 2025-12-31 14:30:00 print(dt.year) # 2025 (이제 계산 가능!) print(dt + timedelta(days=1)) # 다음 날
strptime의 형식이 실제 문자열과 다르면 ValueError가 납니다. "2025/12/31"을 "%Y-%m-%d"(하이픈)로 파싱하려 하면 실패합니다. 구분자까지 정확히 맞춰야 합니다.타임존 다루기
같은 순간이라도 지역마다 시각이 다릅니다(서울 21시 = 런던 12시). 시간대를 명시하지 않은 datetime을 "naive"(순진한), 명시한 것을 "aware"(인식하는)라고 합니다.
Python 3.9부터 표준 zoneinfo로 세계 시간대를 다룹니다.
from datetime import datetime from zoneinfo import ZoneInfo # UTC(세계 표준시) 기준 시각 utc = datetime(2025, 12, 31, 12, 0, tzinfo=ZoneInfo("UTC")) print(utc) # 2025-12-31 12:00:00+00:00 # 서울 시각으로 변환 seoul = utc.astimezone(ZoneInfo("Asia/Seoul")) print(seoul) # 2025-12-31 21:00:00+09:00 (+9시간) # 뉴욕 시각으로 변환 ny = utc.astimezone(ZoneInfo("America/New_York")) print(ny) # 2025-12-31 07:00:00-05:00 (-5시간)
astimezone은 "같은 순간"을 다른 시간대의 표시로 바꿉니다(시간이 달라지는 게 아니라 표현이 달라짐).
"Asia/Seoul", "America/New_York" 같은 IANA 표준 이름을 씁니다. 서버·로그를 다룰 때는 UTC로 저장하고 표시할 때만 지역 시간으로 변환하는 것이 정석입니다. 시간대를 섞으면 버그의 온상이 됩니다.📎 UTC(Coordinated Universal Time)는 세계 표준시로, 시간대 계산의 기준점입니다. "협정 세계시"라고도 합니다.
⭐ 코드 실행 시간 측정
"이 함수가 얼마나 걸리나?"를 잴 때는 datetime이 아니라 time.perf_counter()를 씁니다. 가장 정밀한 시간 측정용 함수입니다.
import time start = time.perf_counter() total = sum(range(1_000_000)) # 측정할 작업 elapsed = time.perf_counter() - start print(f"걸린 시간: {elapsed:.4f}초") # 걸린 시간: 0.0xxx초
perf_counter()는 어떤 절대 시각이 아니라 "흘러간 시간을 재는 스톱워치"입니다. 시작과 끝에서 호출해 차이를 구하면 경과 시간이 나옵니다.
@measure 데코레이터가 바로 이 perf_counter로 함수 실행 시간을 쟀습니다. 데코레이터 + 시간 측정을 결합하면 어떤 함수든 시간을 잴 수 있습니다.time.sleep: 잠시 멈추기
time.sleep(초)는 프로그램을 지정한 시간만큼 멈춥니다. 재시도 간격, 속도 제한 등에 씁니다.
import time print("시작") time.sleep(1) # 1초 대기 print("1초 후")
나쁜 예 ❌ vs 좋은 예 ✅
# ❌ 나쁜 예: 날짜를 문자열로 직접 계산 date_str = "2025-12-31" # "다음 날"을 구하려면? 31 다음은 32가 아니라 다음 달 1일... # 문자열로는 월말·연말·윤년 처리가 악몽 # ✅ 좋은 예: datetime에 맡기기 from datetime import datetime, timedelta dt = datetime.strptime("2025-12-31", "%Y-%m-%d") next_day = dt + timedelta(days=1) print(next_day.strftime("%Y-%m-%d")) # 2026-01-01 (정확!)
이 장에서 배운 것
- 날짜·시간은
datetime모듈에 맡긴다.date(날짜),datetime(날짜+시간),timedelta(간격). timedelta로 계산한다: 날짜 ± 간격 = 날짜, 날짜 − 날짜 = 간격(.days).strftime(날짜→문자열, 만들기)과strptime(문자열→날짜, 파싱).%Y-%m-%d형식 기호를 쓴다.- 타임존은
zoneinfo로 다룬다. UTC로 저장하고 표시할 때 변환하는 것이 정석이다. - 코드 실행 시간은
time.perf_counter()로 측정한다.time.sleep()으로 잠시 멈춘다.
🧪 실습 문제
문제 1. date를 이용해 2025년 12월 25일이 무슨 요일인지 weekday()로 출력하세요. (월=0 기준)
문제 2. 오늘부터 100일 후의 날짜를 구하는 코드를 작성하세요. (date.today()와 timedelta)
문제 3. 다음 두 날짜 사이가 며칠 차이인지 출력하세요.
from datetime import date d1 = date(2025, 1, 1) d2 = date(2025, 12, 31)
문제 4. datetime(2025, 7, 15, 9, 5)를 strftime으로 2025/07/15 09:05 형식의 문자열로 만드세요.
문제 5. 문자열 "2025-06-24 18:30"을 strptime으로 datetime 객체로 바꾼 뒤, 30분을 더해 출력하세요.
<details>
<summary>✅ 정답·해설 보기</summary>
1.
from datetime import date d = date(2025, 12, 25) print(d.weekday()) # 3 (목요일)
2.
from datetime import date, timedelta print(date.today() + timedelta(days=100))
3.
from datetime import date d1 = date(2025, 1, 1) d2 = date(2025, 12, 31) print((d2 - d1).days) # 364
4.
from datetime import datetime dt = datetime(2025, 7, 15, 9, 5) print(dt.strftime("%Y/%m/%d %H:%M")) # 2025/07/15 09:05
5.
from datetime import datetime, timedelta dt = datetime.strptime("2025-06-24 18:30", "%Y-%m-%d %H:%M") print(dt + timedelta(minutes=30)) # 2025-06-24 19:00:00
</details>
◀️ 이전 장: 22. 로깅 | ▶️ 다음 장: 24. 동시성 기초