3.13 计算上一个周五的日期¶
问题¶
ä½ éœ€è¦�一个通用方法æ�¥è®¡ç®—䏀呍䏿Ÿ�一天上一次出现的日期,例如上一个周五的日期。
解决方案¶
Pythonçš„ datetime 模å�—䏿œ‰å·¥å…·å‡½æ•°å’Œç±»å�¯ä»¥å¸®åŠ©ä½ æ‰§è¡Œè¿™æ ·çš„è®¡ç®—ã€‚
下é�¢æ˜¯å¯¹ç±»ä¼¼è¿™æ ·çš„问题的一个通用解决方案:
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
Topic: 最�的周五
Desc :
"""
from datetime import datetime, timedelta
weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
'Friday', 'Saturday', 'Sunday']
def get_previous_byday(dayname, start_date=None):
if start_date is None:
start_date = datetime.today()
day_num = start_date.weekday()
day_num_target = weekdays.index(dayname)
days_ago = (7 + day_num - day_num_target) % 7
if days_ago == 0:
days_ago = 7
target_date = start_date - timedelta(days=days_ago)
return target_date
在交互å¼�解释器ä¸ä½¿ç”¨å¦‚下:
>>> datetime.today() # For reference
datetime.datetime(2012, 8, 28, 22, 4, 30, 263076)
>>> get_previous_byday('Monday')
datetime.datetime(2012, 8, 27, 22, 3, 57, 29045)
>>> get_previous_byday('Tuesday') # Previous week, not today
datetime.datetime(2012, 8, 21, 22, 4, 12, 629771)
>>> get_previous_byday('Friday')
datetime.datetime(2012, 8, 24, 22, 5, 9, 911393)
>>>
�选的 start_date �数�以由�外一个 datetime 实例��供。比如:
>>> get_previous_byday('Sunday', datetime(2012, 12, 21))
datetime.datetime(2012, 12, 16, 0, 0)
>>>
讨论¶
上é�¢çš„算法原ç�†æ˜¯è¿™æ ·çš„ï¼šå…ˆå°†å¼€å§‹æ—¥æœŸå’Œç›®æ ‡æ—¥æœŸæ˜ å°„åˆ°æ˜ŸæœŸæ•°ç»„çš„ä½�置上(星期一索引为0), ç„¶å�Žé€šè¿‡æ¨¡è¿�ç®—è®¡ç®—å‡ºç›®æ ‡æ—¥æœŸè¦�ç»�过多少天æ‰�能到达开始日期。然å�Žç”¨å¼€å§‹æ—¥æœŸå‡�去那个时间差å�³å¾—到结果日期。
å¦‚æžœä½ è¦�åƒ�è¿™æ ·æ‰§è¡Œå¤§é‡�的日期计算的è¯�ï¼Œä½ æœ€å¥½å®‰è£…ç¬¬ä¸‰æ–¹åŒ… python-dateutil æ�¥ä»£æ›¿ã€‚
比如,下é�¢æ˜¯æ˜¯ä½¿ç”¨ dateutil 模å�—ä¸çš„ relativedelta() 函数执行å�Œæ ·çš„计算:
>>> from datetime import datetime
>>> from dateutil.relativedelta import relativedelta
>>> from dateutil.rrule import *
>>> d = datetime.now()
>>> print(d)
2012-12-23 16:31:52.718111
>>> # Next Friday
>>> print(d + relativedelta(weekday=FR))
2012-12-28 16:31:52.718111
>>>
>>> # Last Friday
>>> print(d + relativedelta(weekday=FR(-1)))
2012-12-21 16:31:52.718111
>>>