<think>我们需要计算多日期分段的加班费,每个分段可能有不同的加班类型(平日、周末、法定假日),并且每个分段有自己的加班小时数。思路:1.让用户输入多个加班时间段,每个时间段包括日期、加班小时数、加班类型。2.对于每个时间段,根据日期判断是平日、周末还是法定假日(这里法定假日需要预设或者从外部数据源获取,为简化,我们假设用户直接选择类型)3.根据加班类型应用不同的倍数计算每个时间段的加班费,然后累加。改进:我们允许用户输入日期,然后自动判断是工作日还是周末(法定假日需要额外配置,我们先不考虑自动判断法定假日,而是让用户选择类型,因为法定假日每年不同)步骤:1.输入基本时薪2.输入多个加班时间段(日期、小时数、类型)3.计算每个时间段的加班费并累加注意:日期格式处理,我们使用datetime模块。由于法定假日需要配置,我们可以先内置一个法定假日列表(例如2023年的中国法定假日),或者允许用户自定义。这里为了简化,我们让用户自己选择类型,而不根据日期自动判断类型(因为自动判断需要区分工作日和周末,还要考虑调休等,比较复杂)。因此,我们设计如下:用户输入每个加班记录时,输入日期(用于记录和显示)、加班小时数、加班类型(1-平日,2-周末,3-法定假日)。如果希望根据日期自动判断是平日还是周末(不判断法定假日),那么类型可以只让用户选择法定假日,其他由程序判断。但是这样就需要用户区分法定假日,所以我们还是采用用户指定类型的方式。代码结构:1.输入基本时薪2.循环输入加班记录,直到用户选择退出3.每条记录包括:日期字符串(转换为日期对象,但计算中不需要,仅用于显示和记录)、加班小时数、加班类型4.计算每条记录的加班费:时薪*小时数*倍数(平日1.5,周末2.0,法定假日3.0)5.累加总加班费6.显示详细计算过程和总结果另外,我们将记录保存到文件,包括每条记录的明细和总结果。代码实现:</think>### 多日期分段加班费计算实现方案
要实现多日期分段加班费计算,需要处理多个日期区间内的不同加班类型和小时数。以下是一个完整的解决方案:
```python
from datetime import datetime, timedelta
import csv
# 法定节假日配置(示例数据)
HOLIDAYS = {
'2023-01-01': "元旦",
'2023-01-22': "春节",
'2023-04-05': "清明节",
'2023-05-01': "劳动节",
'2023-06-22': "端午节",
'2023-09-29': "中秋节",
'2023-10-01': "国庆节"
}
def is_holiday(date):
"""检查日期是否为法定节假日"""
return date.strftime('%Y-%m-%d') in HOLIDAYS
def get_overtime_multiplier(date):
"""根据日期确定加班倍数"""
if is_holiday(date):
return 3.0 # 法定节假日3倍
elif date.weekday() >= 5: # 周六或周日
return 2.0 # 周末2倍
else:
return 1.5 # 平日1.5倍
def calculate_segment_pay(hourly_wage, start_time, end_time):
"""计算单个时间段的加班费"""
# 计算加班小时数
hours = (end_time - start_time).total_seconds() / 3600
# 获取加班倍数
multiplier = get_overtime_multiplier(start_time.date())
# 计算该段加班费
return hourly_wage * hours * multiplier, hours, multiplier
def calculate_total_overtime_pay():
"""计算多日期分段加班费主函数"""
print("===== 多日期分段加班费计算器 =====")
try:
# 获取基本输入
hourly_wage = float(input("请输入每小时基本工资(元): "))
# 获取分段加班数据
segments = []
while True:
print("\n=== 添加加班时间段 (输入空值结束) ===")
start_str = input("开始时间(YYYY-MM-DD HH:MM): ")
if not start_str: break
end_str = input("结束时间(YYYY-MM-DD HH:MM): ")
if not end_str: break
try:
start_time = datetime.strptime(start_str, '%Y-%m-%d %H:%M')
end_time = datetime.strptime(end_str, '%Y-%m-%d %H:%M')
# 验证时间顺序
if end_time <= start_time:
print("错误:结束时间必须晚于开始时间")
continue
segments.append((start_time, end_time))
except ValueError:
print("错误:时间格式不正确,请使用 YYYY-MM-DD HH:MM 格式")
except ValueError:
print("错误:请输入有效的数字")
return
# 计算各段加班费
total_pay = 0.0
results = []
for i, (start, end) in enumerate(segments, 1):
segment_pay, hours, multiplier = calculate_segment_pay(hourly_wage, start, end)
total_pay += segment_pay
# 存储结果用于显示和导出
results.append({
'segment': i,
'date': start.date(),
'start': start.time(),
'end': end.time(),
'hours': round(hours, 2),
'multiplier': multiplier,
'pay': round(segment_pay, 2)
})
# 显示结果
print("\n===== 计算结果 =====")
print(f"基本时薪: {hourly_wage:.2f}元/小时")
print(f"总加班费: {total_pay:.2f}元")
print(f"计算日期: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print("\n===== 分段明细 =====")
for result in results:
print(f"时间段{result['segment']}: {result['date']} {result['start']}到{result['end']}")
print(f" 时长: {result['hours']}小时, 倍数: {result['multiplier']}倍, 加班费: {result['pay']:.2f}元")
# 导出到CSV
export_csv(results, total_pay, hourly_wage)
print("\n结果已导出到 overtime_report.csv")
def export_csv(results, total_pay, hourly_wage):
"""导出结果到CSV文件"""
with open('overtime_report.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['多日期分段加班费报告'])
writer.writerow(['计算时间', datetime.now().strftime('%Y-%m-%d %H:%M:%S')])
writer.writerow(['基本时薪', f'{hourly_wage}元/小时'])
writer.writerow(['总加班费', f'{total_pay:.2f}元'])
writer.writerow([])
writer.writerow(['时间段', '日期', '开始时间', '结束时间', '时长(小时)', '倍数', '加班费(元)'])
for result in results:
writer.writerow([
result['segment'],
result['date'],
result['start'].strftime('%H:%M'),
result['end'].strftime('%H:%M'),
result['hours'],
result['multiplier'],
result['pay']
])
if __name__ == "__main__":
calculate_total_overtime_pay()
```
### 代码详解
1. **日期处理与加班类型判断**
- `is_holiday()`: 检查日期是否为法定节假日(使用预设的节假日字典)
- `get_overtime_multiplier()`: 根据日期类型返回加班倍数
- 法定节假日: 3.0倍
- 周末: 2.0倍
- 平日: 1.5倍
2. **分段计算逻辑**
- `calculate_segment_pay()`: 计算单个时间段的加班费
- 计算精确的小时数(支持分钟级计算)
- 应用相应的加班倍数
- `calculate_total_overtime_pay()`: 主函数,处理多时间段输入
- 支持添加多个时间段直到用户输入空值
- 验证时间顺序(结束时间必须晚于开始时间)
3. **结果展示与导出**
- 显示详细的分段计算结果
- `export_csv()`: 将结果导出为结构化的CSV文件
- 包含总加班费和详细的分段信息
- 使用UTF-8编码支持中文
### 使用示例
```
===== 多日期分段加班费计算器 =====
请输入每小时基本工资(元): 50
=== 添加加班时间段 (输入空值结束) ===
开始时间(YYYY-MM-DD HH:MM): 2023-08-15 18:30
结束时间(YYYY-MM-DD HH:MM): 2023-08-15 21:00
=== 添加加班时间段 (输入空值结束) ===
开始时间(YYYY-MM-DD HH:MM): 2023-08-19 09:00
结束时间(YYYY-MM-DD HH:MM): 2023-08-19 18:00
=== 添加加班时间段 (输入空值结束) ===
开始时间(YYYY-MM-DD HH:MM):
===== 计算结果 =====
基本时薪: 50.00元/小时
总加班费: 1375.00元
计算日期: 2023-08-15 15:45:22
===== 分段明细 =====
时间段1: 2023-08-15 18:30:00到21:00:00
时长: 2.5小时, 倍数: 1.5倍, 加班费: 187.50元
时间段2: 2023-08-19 09:00:00到18:00:00
时长: 9.0小时, 倍数: 2.0倍, 加班费: 900.00元
结果已导出到 overtime_report.csv
```
### 优化建议
1. **节假日管理**
- 从外部API或文件加载节假日数据
- 添加节假日管理功能(增删改查)
2. **时间重叠检查**
- 添加逻辑防止用户输入重叠的时间段
- 自动合并相邻时间段
3. **图形界面**
- 使用PyQt/Tkinter创建可视化界面
- 添加日历组件选择日期
4. **国际化支持**
- 添加不同国家/地区的加班规则
- 支持多语言界面