파이썬 최신 보고서 파일 선택: 수정 시간 대신 파일명 날짜와 중복 검사
파일명에서 업무 날짜를 검증해 기준일 이하의 최신 날짜를 찾고, 같은 날짜 후보가 여러 개면 자동 선택을 중단하세요.
적용 환경: Python 3.14 표준 라이브러리. 2026-10-22 확인. Windows Python 3.14.4에서 아래 예제를 임시 작업 폴더에서 실행하고 assert 및 예상 예외 검사를 통과했습니다. 실제 회사 자료·외부 서비스는 사용하지 않았습니다.
업무 날짜와 파일 수정 시간은 다릅니다
수정 시간은 파일 시스템 메타데이터이고 보고서가 집계한 날짜 자체가 아닙니다. 오래된 보고서를 다시 저장하거나 전송 도구가 시간을 바꾸면 수정 시간 순서와 업무 날짜 순서가 달라질 수 있습니다. 복사 도구가 시간을 보존하는 경우도 있으므로 복사하면 항상 수정 시간이 바뀐다고 가정하지 마세요. 파일명 날짜를 신뢰하려면 생성 측과 명명 규칙을 먼저 합의해야 합니다.
선택할 이름 규칙과 기준일을 명시합니다
예제는 폴더 바로 아래의 report_YYYY-MM-DD.csv 또는 report_YYYY-MM-DD_rev2.csv 같은 이름만 후보로 받습니다. rev 뒤에는 1 이상의 정수를 허용합니다. 확장자는 소문자 .csv로 고정하고 임시 파일·다른 접두사·하위 폴더는 처리하지 않습니다. 기준일은 date(2026, 10, 22)로 주입해 테스트가 실행 날짜에 따라 달라지지 않게 했습니다.
직접 실행하는 최소 예제
from pathlib import Path
from datetime import date
from tempfile import TemporaryDirectory
import os
import re
NAME = re.compile(r"report_([0-9]{4}-[0-9]{2}-[0-9]{2})(?:_rev[1-9][0-9]*)?\.csv")
def select_report(folder, as_of):
candidates = []
for path in Path(folder).iterdir():
match = NAME.fullmatch(path.name)
if match is None:
continue
if path.is_symlink():
raise ValueError("보고서 후보에 심볼릭 링크가 있습니다")
if not path.is_file():
continue
# 이름이 맞는데 날짜가 잘못되었으면 조용히 제외하지 않습니다.
report_day = date.fromisoformat(match.group(1))
if report_day <= as_of:
candidates.append((report_day, path))
if not candidates:
raise FileNotFoundError("기준일 이하의 보고서가 없습니다")
latest_day = max(day for day, _ in candidates)
latest = [path for day, path in candidates if day == latest_day]
if len(latest) != 1:
raise ValueError("최신 날짜 후보가 여러 개입니다: 승인본을 확인하세요")
return latest[0]
def expect_error(error, folder, as_of):
try:
select_report(folder, as_of)
except error:
return
raise AssertionError("예상한 오류가 발생하지 않았습니다")
with TemporaryDirectory() as tmp:
folder = Path(tmp)
as_of = date(2026, 10, 22)
expect_error(FileNotFoundError, folder, as_of)
old = folder / "report_2026-10-20.csv"
current = folder / "report_2026-10-21.csv"
for name in [old.name, current.name, "report_2026-10-23.csv", "notes.txt"]:
(folder / name).write_text("sample", encoding="utf-8")
# 오래된 업무 보고서를 나중에 복사한 상황을 합성합니다.
os.utime(current, (1000, 1000))
os.utime(old, (2000, 2000))
assert old.stat().st_mtime > current.stat().st_mtime
assert select_report(folder, as_of) == current
duplicate = folder / "report_2026-10-21_rev2.csv"
duplicate.write_text("sample", encoding="utf-8")
expect_error(ValueError, folder, as_of)
duplicate.unlink() # 임시 폴더에서 만든 합성 파일만 제거합니다.
(folder / "report_2026-02-30.csv").write_text("sample", encoding="utf-8")
expect_error(ValueError, folder, as_of)
print("수정 시간이 더 늦은 10월 20일 파일 대신 10월 21일 보고서 선택")
print("미래 날짜 제외·후보 없음·최신일 중복·잘못된 날짜 검사 통과")
검증한 출력
수정 시간이 더 늦은 10월 20일 파일 대신 10월 21일 보고서 선택 미래 날짜 제외·후보 없음·최신일 중복·잘못된 날짜 검사 통과
오래된 파일의 수정 시간이 더 늦은 상황을 재현합니다
임시 폴더에 10월 20일·21일·23일 이름의 합성 파일을 만들고 os.utime으로 20일 파일의 수정 시간을 더 뒤로 설정합니다. 기준일 22일에서는 미래인 23일을 빼고 21일 파일을 선택해야 합니다. 이어 같은 21일의 rev2 파일을 추가하면 어느 것이 승인본인지 알 수 없으므로 예외로 멈춥니다. 파일명 숫자가 크다는 이유만으로 개정본을 채택하지 않습니다.
정규식과 날짜 객체를 함께 사용하는 이유
정규식은 자릿수와 구분 기호를 검사할 뿐 2월 30일이 유효한지는 판단하지 못합니다. date.fromisoformat이 달력상의 날짜를 확인합니다. 이름 규칙에는 맞지만 날짜가 틀린 후보는 조용히 무시하지 않고 실패시키는 정책입니다. 규칙 자체가 다른 파일은 제외하므로, 입력 폴더에 잘못된 이름이 없는지 별도 목록 검사가 필요한 업무도 있습니다.
선택과 읽기 사이에 파일이 바뀔 수 있습니다
함수는 선택한 Path를 반환할 뿐 파일이 완성됐거나 이후 바뀌지 않음을 보장하지 않습니다. 작성 중 파일을 읽지 않으려면 생산 측이 임시 이름으로 쓰고 완료 후 확정 이름으로 넘기는 절차나 완료 표식을 합의하세요. 재현이 중요하면 선택 직후 원본 식별자·해시를 기록하고 고정 사본을 대상으로 검증하는 단계가 추가로 필요합니다.
안전한 적용 범위
이 코드는 기존 업무 파일을 변경하거나 삭제하지 않습니다. 테스트의 unlink는 TemporaryDirectory 안에서 직접 만든 중복 파일만 제거합니다. 후보 심볼릭 링크는 거부하지만 경쟁 상태나 모든 Windows 재분석 지점까지 막는 보안 샌드박스는 아닙니다. 권한을 통제한 입력 폴더에서 사용하고, 파일명 날짜가 내용 날짜와 같은지도 실제 파서의 검증 단계에서 확인하세요.
자주 묻는 질문
오늘 날짜를 코드에서 자동으로 구하면 안 되나요?
가능하지만 운영 기준 시간대와 마감일 규칙을 정한 뒤 호출부에서 업무 날짜를 계산해 전달하세요. 테스트에는 고정 날짜를 쓰는 편이 재현에 유리합니다.
최신 날짜에 파일이 두 개면 rev가 큰 것을 고르면 되나요?
생성 측이 그 의미를 보장할 때만 가능합니다. 이 예제는 승인본 규약이 없다고 가정하므로 중복을 오류로 처리합니다.
최신 날짜가 없어도 가장 가까운 과거 파일을 고르나요?
예제는 기준일 이하 후보 중 최대 날짜를 선택하므로 그렇습니다. 당일 파일이 필수인 배치라면 선택 결과의 날짜가 기준일과 같은지 추가 검사해야 합니다.
공식 문서와 확인일
다음 Python 공식 문서를 2026-10-22에 직접 확인하고 예제와 대조했습니다. 합성 입력의 숫자와 결과는 위 코드를 실행해 재현한 값입니다.
관련 가이드와 다음 검사
작성 안내: AI 보조로 작성했으며 합성 자료로 로컬 코드의 결과를 검증했습니다. 운영자의 실제 경험이나 사람 전문가 검수를 주장하지 않습니다. 입력 계약과 환경이 달라지면 업무용 자료에 적용하기 전에 별도 테스트를 추가하세요.
댓글
댓글 쓰기