【问题标题】:Calculate if today's date is a recurring date for a given date计算今天的日期是否是给定日期的重复日期
【发布时间】:2015-12-26 00:48:06
【问题描述】:

给定“开始”日期和频率(每月、每季度、每半年、每年),我如何计算今天是否是执行所需操作的日期?

例如,开始日期为 2010-01-01,频率为每月。一个 cron 作业每天都会运行一个 Django 管理命令,所以在 2010 年 2 月 1 日,应该执行所需的操作(不管是什么,对这个问题并不重要)。

【问题讨论】:

    标签: python django date


    【解决方案1】:

    这实际上比我最初想象的要简单。因为所有这些间隔都发生在一个月内,所以计算起来非常简单。它利用了dateutil 中的relativedelta 对象。

    from datetime import date
    from dateutil.relativedelta import relativedelta
    
    starts_at = date(2010, 1, 1)
    today = date(2010, 2, 1)  # as an example
    diff = relativedelta(today, starts_at)
    
    if diff.days == 0:  # there must be no days difference between two dates
        if diff.months % 12 == 0:  # this is a year interval
            do_something('annual')
        elif diff.months % 6 == 0:  # this is a six month interval
            do_something('bi_annual')
        elif diff.months % 3 == 0:  # this is a three month interval
            do_something('quarter')
        else:  # this is a month interval
            do_something('month')
    

    【讨论】:

    • 我想每个do_something() 都不一样?
    • diff.months % 1 也不总是为 0 吗?
    • @PadraicCunningham 我已经更新了答案,感谢您指出该错误。
    • 您可能希望从 12 点开始,12 % 3 == 0 或者即使一年过去了,您也永远无法达到 elif,间隔 6 或 12 个月,最后一个 elif 也可以是 else永远是真的
    • @PadraicCunningham 这样看起来更好吗?
    【解决方案2】:

    要查看今天是否是重复日期,您可以使用today in recurring_rule

    from datetime import datetime
    from dateutil.rrule import rrule, MONTHLY  # $ pip install python-dateutil
    
    starts_at = datetime(2010, 1, 1)
    today = datetime(2010, 2, 1) 
    interval = {'monthly': 1, 'quarterly': 3,
                'bi-annually': 6, 'annually': 12}[frequency]
    if today in rrule(MONTHLY, dtstart=starts_at, interval=interval):
        print('today is a recurring date')
    

    dateutil.rrule 允许您根据RFC 2445 创建循环规则。

    如果您只需要支持每月、每季度、每半年、每年频率的简单规则,这可能有点过头了,但它在更复杂的情况下很有用。

    【讨论】:

      【解决方案3】:

      有一个很棒的Delorean library 有相关的stops() function。这个想法是找出今天的日期是否是一个范围的“停止”之一。示例实现:

      from datetime import datetime
      
      import delorean
      from delorean import stops
      
      
      def is_it_time(start_date, frequency):
          today = datetime.now()
          today_date = today.date()
      
          try:
              next(stop for stop in stops(frequency, start=start_date, stop=today)
                   if stop.date == today_date)
              return "It's time."
          except StopIteration:
              return "It's not the time."
      
      print is_it_time(datetime(2010, 1, 21), delorean.MONTHLY)  
      print is_it_time(datetime(2010, 1, 22), delorean.MONTHLY)
      

      打印:

      It's time.
      It's not the time.
      

      请注意,此处的 frequency 必须是 Delorean 频率常数之一,但是,如果您需要自定义频率值 - 只需将它们适当地映射到 Delorean 常数即可。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-31
        • 1970-01-01
        相关资源
        最近更新 更多