이번 편의 목표: 날짜 검증·월 필터링·간단한 패턴 검사를 수행합니다.

지출의 날짜를 문자열로 저장하면 `2026-02-30`도 글자로는 저장할 수 있습니다. 하지만 실제 달력에는 없는 날입니다. 날짜처럼 의미가 있는 값은 문자열의 모양만 검사해서는 부족합니다.

달력 규칙은 날짜 도구에 맡긴다

Python
from datetime import date, timedelta
import re

text = "2026-10-03"
recorded = date.fromisoformat(text)
print(recorded.year)
print(recorded.isoformat())
print((recorded + timedelta(days=7)).isoformat())

expenses = [
    {"date": "2026-09-30", "amount": 3000},
    {"date": "2026-10-03", "amount": 4500},
    {"date": "2026-10-04", "amount": 8000},
]
month = "2026-10"
selected = [row for row in expenses if row["date"].startswith(month)]
print(sum(row["amount"] for row in selected))

code = "EXP-0042"
print(re.fullmatch(r"EXP-[0-9]{4}", code) is not None)

주요 출력은 `2026`, `2026-10-03`, `2026-10-10`, `12500`, `True`입니다. `date.fromisoformat()`은 날짜 문자열을 날짜 객체로 읽습니다. 존재하지 않는 날짜에는 `ValueError`가 납니다. `timedelta(days=7)`은 7일의 기간을 나타냅니다.

월별 필터에서 문자열 접두사를 사용할 수 있는 이유는 모든 날짜가 검증된 `YYYY-MM-DD` 형식이라고 전제했기 때문입니다. `2026-1-3`처럼 형식이 섞이면 정렬이나 접두사 검색이 틀어질 수 있습니다. 저장할 때 `isoformat()`으로 정규화하면 이후 처리가 단순해집니다.

모양 검사와 의미 검사는 두 단계다

`re.fullmatch()`는 문자열 전체가 패턴과 맞는지 확인합니다. `r"EXP-[0-9]{4}"`에서 `r`은 백슬래시를 많이 쓰는 패턴을 편하게 적는 원시 문자열 표시이고, `[0-9]`는 숫자 한 글자, `{4}`는 네 번 반복입니다. 결과는 일치 객체 또는 `None`입니다.

날짜에 `r"[0-9]{4}-[0-9]{2}-[0-9]{2}"` 패턴을 적용하면 자리수와 구분자는 검사할 수 있습니다. 그러나 `2026-99-99`도 그 모양에는 맞습니다. 마지막 프로젝트는 정규식으로 엄격한 표기 형식을 확인하고 `date.fromisoformat()`으로 실제 날짜를 확인합니다.

정규식이 필요하지 않은 곳

`.startswith()`, `.endswith()`, `in`, `.split()`만으로 충분하면 그 기능을 사용하세요. 정규식은 복잡한 문자열 규칙을 표현할 때 유용하지만, 단순한 접미사 검사까지 패턴으로 바꾸면 읽기 어려워질 수 있습니다.

날짜와 시간도 구분해야 합니다. `date`는 날짜만 다룹니다. 여러 시간대의 사건 순서를 기록하려면 시간대가 있는 `datetime` 등 별도 설계가 필요합니다. 이번 지출 기록기는 사용자가 입력한 달력 날짜만 저장합니다.

직접 해 보기

`2026-02-28`과 `2026-02-30`을 각각 날짜로 읽고 성공 또는 실패를 출력하세요.

해설

Python
from datetime import date

for text in ["2026-02-28", "2026-02-30"]:
    try:
        value = date.fromisoformat(text)
    except ValueError:
        print(f"잘못된 날짜: {text}")
    else:
        print(f"확인한 날짜: {value.isoformat()}")

첫 날짜는 성공하고 두 번째는 실패합니다. `try`의 `else`는 예외가 없을 때 실행됩니다. 검증을 도구에 맡기면 윤년 규칙까지 직접 코딩할 필요가 없습니다.