zhyq0826 / zhyq0826.github.io

三月沙的博客
http://sanyuesha.com
6 stars 1 forks source link

关于车检年限计算的问题 #72

Closed zhyq0826 closed 7 years ago

zhyq0826 commented 7 years ago

车检的要根据当前车的车龄来计算下次年检或领标的时间,而且根据车型、是否出过事故等不同具有不同的计算规则,因此需要计算车龄。

由于每年的天数是不一定都是 365 天,闰年是 366 天,所以为了避免这多出来的一天带来的误差,计算免检车辆的免检的时间直接先计算出免检的两次时间,然后根据当前之日计算出是第几次领标,免检车辆的第一次领标时间也需要根据当前时间来计算


first_stamp = arrow.get(
    vst.registration_time, 'local').replace(years=2).naive

second_stamp = arrow.get(
    vst.registration_time, 'local').replace(years=4).naive

first_check_time = arrow.get(
    vst.registration_time, 'local').replace(years=6).naive

today = arrow.get(datetime.date.today(), 'local').naive
if first_stamp < today <= second_stamp:
    vst.next_stamp_time = second_stamp
elif today <= first_stamp:
    vst.next_stamp_time = first_stamp

# 规避每年天数不确定带来的计算误差
if today <= first_check_time:
    vst.next_check_time = first_check_time
else:
    vst.next_check_time = next_check_time

比如 2016 年是个闰年,366 天,比如在 2016.1.1 注册的车辆,到了 2021.1.1 是满 5 年,实际计算以 365 天为一年,到了 2020.12.31 计算车龄就已经到了 5 年,以营运大型车辆为例,没有满 5 年是一年检一次,所以 2020.12.31 这一天如果提交计算实际是没有满 5 年,所以下次年检应该是 2021.1.1 日,如果按照 365 天算,则满了 5 年,所以 6 个月检测一次,则检测时间变成 2021.7.1。

所以计算车龄,最好根据时间年份进行计算,看当前时间落在那些年份之间。

def get_vehicle_age(registration_time, age_base_date=None):
    r_time = arrow.get(registration_time, 'local')
    if age_base_date is None:
        age_base_date = arrow.now().date()
    else:
        age_base_date = arrow.get(age_base_date, 'local').date()

    # first register
    if r_time.date() == age_base_date:
        return 0

    for age in range(1, 50):
        # int age
        if age_base_date == r_time.replace(years=age).date():
            return age

        before_age = r_time.replace(years=age - 1).date() 
        after_age = r_time.replace(years=age).date()  
        if before_age < age_base_date < after_age:
            return (age - 1) + (0.7 if (age_base_date - before_age).days > 182.5 else 0.3)

    return (age_base_date - r_time.date()).days / 365.0