import holidays from datetime import date, timedelta import logging logger = logging.getLogger(__name__) # 베트남 휴일 객체 생성 (캐싱) try: # 2024~2026년 휴일 미리 로드 (범위 명시가 안전할 수 있음) vn_holidays = holidays.VN(years=[2024, 2025, 2026]) logger.info(f"[date_utils] VN holidays loaded for 2024-2026. Total: {len(vn_holidays)}") except Exception as e: logger.error(f"[date_utils] 휴일 정보 로드 실패: {e}") print(f"[date_utils] 휴일 정보 로드 실패: {e}") vn_holidays = {} def is_holiday(d: date) -> bool: """ 해당 날짜가 주말(토,일)이거나 베트남 공휴일인지 확인 """ # 주말 체크 (5: 토요일, 6: 일요일) if d.weekday() >= 5: return True # 공휴일 체크 if d in vn_holidays: return True return False def add_business_days(start_date: date, days: int) -> date: """ start_date로부터 days만큼의 업무일(Business Days)을 더하거나 뺀 날짜를 반환 - days > 0: 미래로 이동 - days < 0: 과거로 이동 - days == 0: start_date가 휴일이면 다음 업무일(미래 방향) 반환, 아니면 그대로 반환 """ current_date = start_date # 0일인 경우: 시작일이 휴일이면 평일이 나올 때까지 전진 if days == 0: while is_holiday(current_date): current_date += timedelta(days=1) return current_date # 이동 방향 설정 step = 1 if days > 0 else -1 days_left = abs(days) while days_left > 0: current_date += timedelta(days=step) # 휴일이면 카운트하지 않음 (건너뜀) if not is_holiday(current_date): days_left -= 1 return current_date def get_holidays_in_range(start_date: date, end_date: date) -> list: """ start_date ~ end_date (inclusive) 기간 내의 휴일 목록(date 객체) 반환 """ holidays_list = [] # 날짜 순서 보정 if start_date > end_date: start_date, end_date = end_date, start_date curr = start_date while curr <= end_date: if is_holiday(curr): holidays_list.append(curr) curr += timedelta(days=1) return holidays_list