Google Sheet工时公式转Django逻辑结果不符的问题排查
解决Django工时计算与Google Sheets公式不一致的问题
原Google Sheets公式的核心逻辑是:分别对开始时间、结束时间单独转换为小时数后,四舍五入到0.25小时(15分钟)的倍数,再计算两者差值;若差值≥8小时,则减去0.5小时。你的Django代码先计算总时长再向下取整,且未单独处理开始/结束时间的取整逻辑,这是导致结果不符的根本原因。
问题点拆解
- Google Sheets的
MROUND(x, 0.25)是四舍五入到最近的0.25倍数,例如:MROUND(7.1, 0.25)→ 7MROUND(7.2, 0.25)→ 7.25MROUND(7.4, 0.25)→ 7.5
- 你的代码用
math.floor(total_hours *4)/4是向下取整,和MROUND的行为完全不同;同时跳过了"单独对开始/结束时间取整"的步骤,逻辑顺序错误。
修正后的Django代码
import math def calculate_total_time(self, start_time, end_time): if start_time is not None and end_time is not None: # 将开始时间转成小时数,四舍五入到0.25倍数(匹配Google Sheets的MROUND) start_hours = start_time.hour + start_time.minute / 60 rounded_start = round(start_hours * 4) / 4 # 对结束时间执行相同的取整操作 end_hours = end_time.hour + end_time.minute / 60 rounded_end = round(end_hours * 4) / 4 # 处理跨天场景(结束时间早于开始时间) if rounded_end < rounded_start: rounded_end += 24 # 计算取整后的时间差 hours_diff = rounded_end - rounded_start # 应用8小时以上减0.5小时的规则 if hours_diff >= 8: hours_diff -= 0.5 return round(hours_diff, 2) # 保留两位小数避免浮点精度问题 else: return 0.00
验证示例
举几个典型场景对比结果:
- 开始时间9:05,结束时间17:10
- Google Sheets:
17.25-9=8.25→ 8.25-0.5=7.75 - 修正后代码:输出7.75,与原公式一致
- Google Sheets:
- 开始时间8:10,结束时间16:05
- Google Sheets:
16-8.25=7.75→ 直接返回7.75 - 修正后代码:输出7.75,与原公式一致
- Google Sheets:
- 跨天场景:开始时间22:30,结束时间6:15
- Google Sheets:
(6.25+24)-22.5=7.75→ 直接返回7.75 - 修正后代码:输出7.75,与原公式一致
- Google Sheets:
内容的提问来源于stack exchange,提问作者ckcAdmin
相关产品推荐
相关产品推荐

