• 3.13 计算最后一个周五的日期
    • 问题
    • 解决方案
    • 讨论

    3.13 计算最后一个周五的日期

    问题

    你需要查找星期中某一天最后出现的日期,比如星期五。

    解决方案

    Python的 datetime 模块中有工具函数和类可以帮助你执行这样的计算。下面是对类似这样的问题的一个通用解决方案:

    1. #!/usr/bin/env python
    2. # -*- encoding: utf-8 -*-
    3. """
    4. Topic: 最后的周五
    5. Desc :
    6. """
    7. from datetime import datetime, timedelta
    8.  
    9. weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
    10. 'Friday', 'Saturday', 'Sunday']
    11.  
    12.  
    13. def get_previous_byday(dayname, start_date=None):
    14. if start_date is None:
    15. start_date = datetime.today()
    16. day_num = start_date.weekday()
    17. day_num_target = weekdays.index(dayname)
    18. days_ago = (7 + day_num - day_num_target) % 7
    19. if days_ago == 0:
    20. days_ago = 7
    21. target_date = start_date - timedelta(days=days_ago)
    22. return target_date

    在交互式解释器中使用如下:

    1. >>> datetime.today() # For reference
    2. datetime.datetime(2012, 8, 28, 22, 4, 30, 263076)
    3. >>> get_previous_byday('Monday')
    4. datetime.datetime(2012, 8, 27, 22, 3, 57, 29045)
    5. >>> get_previous_byday('Tuesday') # Previous week, not today
    6. datetime.datetime(2012, 8, 21, 22, 4, 12, 629771)
    7. >>> get_previous_byday('Friday')
    8. datetime.datetime(2012, 8, 24, 22, 5, 9, 911393)
    9. >>>

    可选的 start_date 参数可以由另外一个 datetime 实例来提供。比如:

    1. >>> get_previous_byday('Sunday', datetime(2012, 12, 21))
    2. datetime.datetime(2012, 12, 16, 0, 0)
    3. >>>

    讨论

    上面的算法原理是这样的:先将开始日期和目标日期映射到星期数组的位置上(星期一索引为0),然后通过模运算计算出目标日期要经过多少天才能到达开始日期。然后用开始日期减去那个时间差即得到结果日期。

    如果你要像这样执行大量的日期计算的话,你最好安装第三方包 python-dateutil 来代替。比如,下面是是使用 dateutil 模块中的 relativedelta() 函数执行同样的计算:

    1. >>> from datetime import datetime
    2. >>> from dateutil.relativedelta import relativedelta
    3. >>> from dateutil.rrule import *
    4. >>> d = datetime.now()
    5. >>> print(d)
    6. 2012-12-23 16:31:52.718111
    7.  
    8. >>> # Next Friday
    9. >>> print(d + relativedelta(weekday=FR))
    10. 2012-12-28 16:31:52.718111
    11. >>>
    12.  
    13. >>> # Last Friday
    14. >>> print(d + relativedelta(weekday=FR(-1)))
    15. 2012-12-21 16:31:52.718111
    16. >>>

    原文:

    http://python3-cookbook.readthedocs.io/zh_CN/latest/c03/p13_determine_last_friday_date.html