바쁜 분은 이것만
- 문자열 → 날짜:
datetime.strptime("2026-10-16 19:00", "%Y-%m-%d %H:%M") - 날짜 → 문자열:
d.strftime("%Y년 %m월 %d일")또는f"{d:%Y-%m-%d}" - 며칠 뒤/차이:
d + timedelta(days=30),(b - a).days
파이썬에서 날짜를 다루다 보면 문자열과 datetime을 계속 오가게 됩니다. 이름이 비슷한 strptime(p = parse, 문자열 → 날짜)과 strftime(f = format, 날짜 → 문자열) 사용법, 그리고 자주 나는 에러를 Python 3.14에서 실행한 결과로 정리했습니다.
1. 문자열 → datetime: strptime
from datetime import datetime, date, timedelta
d = datetime.strptime("2026-10-16 19:00", "%Y-%m-%d %H:%M")
print(repr(d))
datetime.datetime(2026, 10, 16, 19, 0)
두 번째 인자(포맷)는 문자열의 모양을 그대로 적어야 합니다. 자주 쓰는 기호:
| 기호 | 뜻 | 예 |
|---|---|---|
%Y / %y |
연도 4자리 / 2자리 | 2026 / 26 |
%m %d |
월, 일 | 10, 16 |
%H / %I |
시 24시간 / 12시간 | 19 / 07 |
%M %S |
분, 초 | 00, 00 |
%p |
AM/PM | PM |
%a |
요일 약자(영어) | Fri |
대문자 %M은 분, 소문자 %m은 월입니다. 이 둘을 바꿔 쓰는 실수가 가장 흔해요.
2. ValueError: time data ... does not match format
문자열과 포맷이 조금이라도 다르면 이 에러가 납니다. 실제로 나온 메시지들이에요.
datetime.strptime("2026-10-16", "%Y-%m-%d %H:%M")
# ValueError: time data '2026-10-16' does not match format '%Y-%m-%d %H:%M'
datetime.strptime("2026/10/16", "%Y-%m-%d")
# ValueError: time data '2026/10/16' does not match format '%Y-%m-%d'
datetime.strptime("26-10-16", "%Y-%m-%d")
# ValueError: time data '26-10-16' does not match format '%Y-%m-%d'
datetime.strptime("2026-10-16 19:00:00", "%Y-%m-%d %H:%M")
# ValueError: unconverted data remains: :00
datetime.strptime("2026-02-30", "%Y-%m-%d")
# ValueError: day 30 must be in range 1..28 for month 2 in year 2026
- 시간이 없는데 포맷에 시간이 있음 → 포맷에서
%H:%M빼기 - 구분자가 다름(
/vs-) → 포맷도%Y/%m/%d - 연도가 2자리 →
%y - unconverted data remains: 문자열 뒤에 포맷에 없는 부분(여기선 초)이 남음 →
:%S추가 - 2월 30일처럼 없는 날짜는 포맷이 맞아도 에러
3. 함정: 7:00 PM이 오전 7시가 된다
datetime.strptime("2026-10-16 7:00 PM", "%Y-%m-%d %H:%M %p")
datetime.strptime("2026-10-16 7:00 PM", "%Y-%m-%d %I:%M %p")
2026-10-16 07:00:00
2026-10-16 19:00:00
첫 줄은 에러 없이 오전 7시로 읽혔습니다. %p(AM/PM)는 12시간제 %I와 같이 쓸 때만 반영되고, 24시간제 %H와 쓰면 무시돼요. 에러가 안 나서 데이터가 12시간씩 틀어진 걸 한참 뒤에 발견하게 되니, PM이 들어간 문자열은 꼭 %I를 쓰세요.
4. ISO 형식이면 fromisoformat이 더 간단
datetime.fromisoformat("2026-10-16T19:00:00") # 2026-10-16 19:00:00
datetime.fromisoformat("2026-10-16 19:00") # 2026-10-16 19:00:00
"2026-10-16" 같은 표준 형식(API 응답, DB 값)이면 포맷을 안 적어도 됩니다.
5. datetime → 문자열: strftime
d.strftime("%Y년 %m월 %d일 %H시") # '2026년 10월 16일 19시'
d.strftime("%-m월 %-d일 (%a)") # '10월 16일 (Fri)'
f"{d:%y.%m.%d}" # '26.10.16'
["월","화","수","목","금","토","일"][d.weekday()] # '금'
%-m,%-d: 앞의 0 빼기(10월 6일을 "10월 06일"이 아니라 "10월 6일"로). 맥·리눅스에서만 되고 윈도우에서는%#m을 씁니다.%a는 영어 요일이라, 한글 요일은weekday()(월=0 … 일=6)로 리스트에서 꺼내는 게 간단합니다.
6. 날짜 계산: timedelta
a = datetime(2026, 10, 16, 19, 0)
b = datetime(2026, 12, 25, 0, 0)
diff = b - a
print(repr(diff), diff.days, diff.total_seconds())
print(a + timedelta(days=30), a - timedelta(hours=5))
print(date(2026, 12, 25) - date(2026, 10, 16))
datetime.timedelta(days=69, seconds=18000) 69 5979600.0
2026-11-15 19:00:00 2026-10-16 14:00:00
70 days, 0:00:00
datetime끼리 빼면 timedelta가 나옵니다. 19시부터 계산해서 69일 5시간이라 .days는 69예요. 날짜만(date) 빼면 70일입니다. "D-day 며칠"을 셀 땐 date끼리 빼는 게 헷갈리지 않아요.
7. 타입이 섞이면 TypeError
datetime(2026, 10, 16) - date(2026, 10, 1)
# TypeError: unsupported operand type(s) for -: 'datetime.datetime' and 'datetime.date'
"2026-10-16" < datetime(2026, 10, 17)
# TypeError: '<' not supported between instances of 'str' and 'datetime.datetime'
datetime과 date는 바로 계산이 안 되니 dt.date()로 맞추고, 문자열은 먼저 strptime으로 바꾼 뒤 비교하세요.
정리
| 하고 싶은 것 | 코드 |
|---|---|
| 문자열 → 날짜 | datetime.strptime(s, "%Y-%m-%d") |
| ISO 문자열 → 날짜 | datetime.fromisoformat(s) |
| 날짜 → 문자열 | d.strftime("%Y-%m-%d") |
| PM 포함 시간 | %I:%M %p (%H 아님) |
| 며칠 뒤 | d + timedelta(days=n) |
| 며칠 차이 | (date2 - date1).days |
참고: Python 공식 문서 — datetime 모듈, strftime() and strptime() Format Codes
