代码之家  ›  专栏  ›  技术社区  ›  mpen

下周五下午3点怎么算?

  •  11
  • mpen  · 技术社区  · 14 年前

    你怎么计算下周五凌晨3点 datetime 对象?

    澄清: 即,计算日期应始终大于7天,小于或等于14天。


    使用稍微修改过的版本 Mark's solution :

    def _next_weekday(day_of_week=4, time_of_day=datetime.time(hour=3), dt=None):
        if dt is None: dt = datetime.datetime.now()
        dt += datetime.timedelta(days=7)
        if dt.time() < time_of_day: dt = dt.combine(dt.date(), time_of_day)
        else: dt = dt.combine(dt.date(), time_of_day) + datetime.timedelta(days=1)
        return dt + datetime.timedelta((day_of_week - dt.weekday()) % 7)
    
    4 回复  |  直到 14 年前
        1
  •  6
  •   Mark Tolonen    14 年前

    下面是一个功能和一个测试,它满足OP的要求:

    import datetime
    
    _3AM = datetime.time(hour=3)
    _FRI = 4 # Monday=0 for weekday()
    
    def next_friday_3am(now):
        now += datetime.timedelta(days=7)
        if now.time() < _3AM:
            now = now.combine(now.date(),_3AM)
        else:
            now = now.combine(now.date(),_3AM) + datetime.timedelta(days=1)
        return now + datetime.timedelta((_FRI - now.weekday()) % 7)
    
    if __name__ == '__main__':
        start = datetime.datetime.now()
        for i in xrange(7*24*60*60):
            now = start + datetime.timedelta(seconds=i)
            then = next_friday_3am(now)
            assert datetime.timedelta(days=7) < then - now <= datetime.timedelta(days=14)
            assert then.weekday() == _FRI
            assert then.time() == _3AM
    
        2
  •  9
  •   unutbu    14 年前

    如果安装 dateutil ,然后您可以这样做:

    import datetime
    import dateutil.relativedelta as reldate
    
    def following_friday(dt):   
        rd=reldate.relativedelta(
            weekday=reldate.FR(+2),
            hours=+21)
        rd2=reldate.relativedelta(
            hour=3,minute=0,second=0,microsecond=0)
        return dt+rd+rd2
    

    上面, hours=+21 告诉 relativedelta 增加 dt 在找到下个星期五前21小时。所以,如果 dt 是2010年3月12日凌晨2点,加上21小时就到了晚上11点 同一天的 ,但如果 dt 是在凌晨3点之后,然后加上21小时的推送 dt 一直到星期六。

    这是一些测试代码。

    if __name__=='__main__':
        today=datetime.datetime.now()
        for dt in [today+datetime.timedelta(days=i) for i in range(-7,8)]:
            print('%s --> %s'%(dt,following_friday(dt)))
    

    其产生:

    2010-03-05 20:42:09.246124 --> 2010-03-19 03:00:00
    2010-03-06 20:42:09.246124 --> 2010-03-19 03:00:00
    2010-03-07 20:42:09.246124 --> 2010-03-19 03:00:00
    2010-03-08 20:42:09.246124 --> 2010-03-19 03:00:00
    2010-03-09 20:42:09.246124 --> 2010-03-19 03:00:00
    2010-03-10 20:42:09.246124 --> 2010-03-19 03:00:00
    2010-03-11 20:42:09.246124 --> 2010-03-19 03:00:00
    2010-03-12 20:42:09.246124 --> 2010-03-26 03:00:00 
    2010-03-13 20:42:09.246124 --> 2010-03-26 03:00:00
    2010-03-14 20:42:09.246124 --> 2010-03-26 03:00:00
    2010-03-15 20:42:09.246124 --> 2010-03-26 03:00:00
    2010-03-16 20:42:09.246124 --> 2010-03-26 03:00:00
    2010-03-17 20:42:09.246124 --> 2010-03-26 03:00:00
    2010-03-18 20:42:09.246124 --> 2010-03-26 03:00:00
    2010-03-19 20:42:09.246124 --> 2010-04-02 03:00:00
    

    凌晨3点之前:

    two = datetime.datetime(2010, 3, 12, 2, 0)
    for date in [two+datetime.timedelta(days=i) for i in range(-7,8)]:
        result = following_friday(date)
        print('{0}-->{1}'.format(date,result))
    

    产量:

    2010-03-05 02:00:00-->2010-03-12 03:00:00
    2010-03-06 02:00:00-->2010-03-19 03:00:00
    2010-03-07 02:00:00-->2010-03-19 03:00:00
    2010-03-08 02:00:00-->2010-03-19 03:00:00
    2010-03-09 02:00:00-->2010-03-19 03:00:00
    2010-03-10 02:00:00-->2010-03-19 03:00:00
    2010-03-11 02:00:00-->2010-03-19 03:00:00
    2010-03-12 02:00:00-->2010-03-19 03:00:00
    2010-03-13 02:00:00-->2010-03-26 03:00:00
    2010-03-14 02:00:00-->2010-03-26 03:00:00
    2010-03-15 02:00:00-->2010-03-26 03:00:00
    2010-03-16 02:00:00-->2010-03-26 03:00:00
    2010-03-17 02:00:00-->2010-03-26 03:00:00
    2010-03-18 02:00:00-->2010-03-26 03:00:00
    2010-03-19 02:00:00-->2010-03-26 03:00:00
    
        3
  •  4
  •   Alex Martelli    14 年前

    我喜欢 dateutil 一般来说,对于这样的任务,我不理解你想要的启发式方法——正如我所说的,如果我说“下星期五”,而现在是星期四,我会 意味着明天(可能我工作太努力了,忘记了一周中的哪一天)。当然,如果你能严格地指定你的启发式方法,它们肯定是可以编程的,但是如果它们足够古怪,你不太可能发现它们已经在现有的包中为你预先编程了;-)。

        4
  •  2
  •   Tom    14 年前

    根据你的解释…我想你可以这样做:

    from datetime import *
    >>> today = datetime.today()
    >>> todayAtThreeAm = datetime(today.year, today.month, today.day, 3)
    >>> todayAtThreeAm
    datetime.datetime(2010, 3, 12, 3, 0)
    >>> nextFridayAtThreeAm = todayAtThreeAm + timedelta(12 - today.isoweekday())
    >>> nextFridayAtThreeAm
    datetime.datetime(2010, 3, 19, 3, 0)
    

    通知 isoweekday() 周一到周日返回1到7。12表示下星期的星期五。所以12-today.isoweekday()提供了您今天需要添加的正确时间增量。

    希望这有帮助。