如何用Python计算双周服务月度次数并生成客户账单
月度客户账单程序:处理两周一次服务的统计方案
核心思路
针对每两周一次服务的客户,确实不能仅靠当月星期几的数量统计,必须结合历史服务记录判断当月服务周期(是第1、3、5周的对应星期,还是第2、4周的)。你计划新增的confirmed service date列完全可行——通过该列的最近服务日期,就能推算出当月的服务节点。
具体实现方案
1. CSV数据结构建议
CSV可包含以下字段(可结合现有结构调整):
customer_id:客户唯一标识service_frequency:服务频率(weekly代表每周一次,biweekly代表每两周一次)service_weekday:固定服务星期几(0=周一,6=周日)confirmed_service_date:最近一次已完成的服务日期(格式统一为YYYY-MM-DD)
2. 代码实现(替换原有统计逻辑)
from datetime import datetime, timedelta import calendar import csv def calculate_monthly_services(customer, target_year, target_month): freq = customer['service_frequency'] target_weekday = int(customer['service_weekday']) last_service = datetime.strptime(customer['confirmed_service_date'], '%Y-%m-%d').date() # 定义当月的起止日期 month_start = datetime(target_year, target_month, 1).date() month_end = datetime(target_year, target_month, calendar.monthrange(target_year, target_month)[1]).date() service_count = 0 if freq == 'weekly': # 每周服务:直接统计当月对应星期几的数量 _, total_days = calendar.monthrange(target_year, target_month) service_count = sum(1 for day in range(1, total_days+1) if calendar.weekday(target_year, target_month, day) == target_weekday) elif freq == 'biweekly': # 每两周服务:通过最近服务日期判断当月服务节点 # 先找到当月第一个符合服务星期的日期 first_match_day = month_start while first_match_day.weekday() != target_weekday: first_match_day += timedelta(days=1) # 计算最近服务日与第一个匹配日的间隔周数,判断是否属于同一周期 week_diff = (first_match_day - last_service).days // 7 include_current = (week_diff % 2) == 0 # 遍历当月所有匹配星期的日期,交替计数 current_day = first_match_day while current_day <= month_end: if include_current: service_count += 1 include_current = not include_current current_day += timedelta(weeks=1) return service_count def main(): current_year = datetime.now().year current_month = datetime.now().month with open('customers.csv', 'r', newline='', encoding='utf-8') as f: reader = csv.DictReader(f) for customer in reader: count = calculate_monthly_services(customer, current_year, current_month) print(f"客户{customer['customer_id']}当月服务次数:{count}") if __name__ == "__main__": main()
3. 关键逻辑说明
- 每周服务:保留你原本的统计逻辑,直接数出当月对应星期几的总天数。
- 每两周服务:
- 定位当月第一个符合服务星期的日期;
- 通过该日期与最近服务日的间隔周数,判断是否属于客户的服务周期(间隔为偶数周则包含,奇数则跳过);
- 从第一个匹配日开始,每隔一周交替计数,直到当月结束。
补充场景处理
如果是当月新签约的客户,没有历史服务记录,可以在CSV新增start_cycle_type字段(比如odd代表第1、3、5周服务,even代表第2、4周服务),直接用该字段替代历史日期判断逻辑。
内容的提问来源于stack exchange,提问作者Tjunk
相关产品推荐
相关产品推荐

