import datetime from typing import Optional, Dict, Any, List def is_weekend(date: datetime.date) -> bool: """判断是否为周末""" return date.weekday() >= 5 # 周六=5, 周日=6 def is_holiday(date: datetime.date, holidays: list = None) -> Dict[str, Any]: """检测指定日期是否为休息日""" day_of_week = date.weekday() # 0=周一, 6=周日 is_weekend_day = day_of_week >= 5 # 周六、周日 # 检查是否为配置的节假日 configured_holiday = None if holidays: for holiday in holidays: if holiday.date == date: configured_holiday = holiday break is_configured_holiday = configured_holiday is not None return { 'is_holiday': is_weekend_day or is_configured_holiday, 'holiday_type': 'weekend' if is_weekend_day else (configured_holiday.holiday_type if configured_holiday else None), 'holiday_name': configured_holiday.holiday_name if configured_holiday else None, 'is_working_day': configured_holiday.is_working_day if configured_holiday else False } def calculate_hours(start_time: Optional[str], end_time: Optional[str], is_holiday_flag: bool = False) -> str: """工时计算函数""" if not start_time or not end_time or start_time == '-' or end_time == '-': return '0:00' if is_holiday_flag else '-' # 休息日默认显示0:00而不是- try: start = datetime.datetime.strptime(start_time, '%H:%M') end = datetime.datetime.strptime(end_time, '%H:%M') # 处理跨日情况 if end < start: end += datetime.timedelta(days=1) diff = end - start total_minutes = int(diff.total_seconds() / 60) hours = total_minutes // 60 minutes = total_minutes % 60 return f"{hours}:{minutes:02d}" except ValueError: return '0:00' def format_hours_to_decimal(hours: str) -> float: """工时格式转换函数:将"2:42"格式转换为小数格式用于计算""" if hours == '-' or not hours: return 0.0 if ':' in hours: try: parts = hours.split(':') h = int(parts[0]) m = int(parts[1]) if len(parts) > 1 else 0 return h + (m / 60) except ValueError: return 0.0 try: return float(hours) except ValueError: return 0.0 def format_decimal_to_hours(decimal_hours: float) -> str: """将小数工时转换回"HH:MM"格式""" hours = int(decimal_hours) minutes = int((decimal_hours - hours) * 60) return f"{hours}:{minutes:02d}" def calculate_weekly_hours(records: list) -> Dict[str, float]: """工时统计函数(区分工作日和休息日)""" workday_hours = sum([ format_hours_to_decimal(r.get('hours', '0:00')) for r in records if not r.get('is_holiday', False) and r.get('hours') not in ['-', '0:00', None] ]) holiday_hours = sum([ format_hours_to_decimal(r.get('hours', '0:00')) for r in records if r.get('is_holiday', False) and r.get('hours') not in ['-', '0:00', None] ]) return { 'workday_hours': workday_hours, 'holiday_hours': holiday_hours, 'total_hours': workday_hours + holiday_hours } def get_week_info(date: datetime.date) -> str: """获取周信息,如"51周/53周" """ year = date.year week_num = date.isocalendar()[1] # 计算该年总共有多少周 last_day = datetime.date(year, 12, 31) total_weeks = last_day.isocalendar()[1] return f"{week_num}周/{total_weeks}周" def get_day_of_week_chinese(date: datetime.date) -> str: """获取中文星期""" weekdays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] return weekdays[date.weekday()]