You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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. 关键逻辑说明

  • 每周服务:保留你原本的统计逻辑,直接数出当月对应星期几的总天数。
  • 每两周服务:
    1. 定位当月第一个符合服务星期的日期;
    2. 通过该日期与最近服务日的间隔周数,判断是否属于客户的服务周期(间隔为偶数周则包含,奇数则跳过);
    3. 从第一个匹配日开始,每隔一周交替计数,直到当月结束。

补充场景处理

如果是当月新签约的客户,没有历史服务记录,可以在CSV新增start_cycle_type字段(比如odd代表第1、3、5周服务,even代表第2、4周服务),直接用该字段替代历史日期判断逻辑。

内容的提问来源于stack exchange,提问作者Tjunk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 09:04:55