【问题标题】:Generating all dates within a given range in python在python中生成给定范围内的所有日期
【发布时间】:2011-08-17 14:37:51
【问题描述】:

我有两个字符串变量,其中包含 yyyy-mm-dd 格式的日期,如下所示:

date1 = '2011-05-03'
date2 = '2011-05-10'

我想编写代码来生成 date1 到 date2 范围内的所有日期。这如何在 Python 中完成?

【问题讨论】:

标签: python datetime


【解决方案1】:

Pandas 非常适合一般的时间序列,并且直接支持日期范围和日期解析(它是自动的)。

import pandas as pd
date1 = '2011-05-03'
date2 = '2011-05-10'
mydates = pd.date_range(date1, date2).tolist()

它还有很多选项可以让生活更轻松。例如,如果您只想要工作日,则只需换入 bdate_range

https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#generating-ranges-of-timestamps

【讨论】:

    【解决方案2】:

    日期可以像数字一样相互比较,您可以使用 datetime.timedelta 对象进行与日期相关的数学运算。这里没有理由使用 dateutil,也没有理由硬编码 la 'range(9)' 的迭代次数。这真的变得类似于您处理普通旧数字的方式。

    >>> import datetime
    >>> date1 = '2011-05-03'
    >>> date2 = '2011-05-10'
    >>> start = datetime.datetime.strptime(date1, '%Y-%m-%d')
    >>> end = datetime.datetime.strptime(date2, '%Y-%m-%d')
    >>> step = datetime.timedelta(days=1)
    >>> while start <= end:
    ...     print start.date()
    ...     start += step
    ... 
    2011-05-03
    2011-05-04
    2011-05-05
    2011-05-06
    2011-05-07
    2011-05-08
    2011-05-09
    2011-05-10
    >>> 
    

    【讨论】:

      【解决方案3】:
      from dateutil import rrule, parser
      
      date1 = '2011-05-03'
      date2 = '2011-05-10'
      
      dates = list(rrule.rrule(rrule.DAILY,
                               dtstart=parser.parse(date1),
                               until=parser.parse(date2)))
      
      print dates
      

      由于dateutil 不是标准库,您必须将其安装为单独的包。有关格式的更多详细信息,请参阅文档(尤其是 dayfirstyearfirst 开关)。

      【讨论】:

      • 酷。解析器如何知道是 yyyy-mm-dd 还是 yyyy-dd-mm?
      【解决方案4】:

      假设您的日期已经是 datetime.date 类,您可以使用 .fromordinal.toordinal 来创建这个单线器。

      from datetime import date
      
      start_date = date(2011, 5, 3)
      end_date = date(2011, 5, 10)
      
      [date.fromordinal(i) for i in range(start_date.toordinal(), end_date.toordinal())]
      

      结果是独家end_date。将end_date.toordinal() + 1 用于包含end_date 的范围。

      【讨论】:

        【解决方案5】:
        import datetime
        real_date1 = datetime.date(*[int(x) for x in date1.split('-')])
        real_date2 = datetime.date(*[int(x) for x in date2.split('-')])
        date_range =  real_date2 - real_date1
        dates = list()
        for days in xrange(date_range.days):
            dates.append(real_date1 + datetime.timedelta(days))
        
        print dates
        

        对于 python 3 使用 range 而不是 xrange

        【讨论】:

          【解决方案6】:
          import time
          
          def dates_between(start, end):
            start_epoch = int(time.mktime(time.strptime(start, "%Y-%m-%d")))
            end_epoch = int(time.mktime(time.strptime(end, "%Y-%m-%d"))) + 1 #include end
            return range(start_epoch, end_epoch, 86400)
          

          【讨论】:

          • 这会在没有 86,400 纪元秒长的日子里中断,但我还不足以知道这个假设是否“足够好”。
          【解决方案7】:

          我喜欢这个,因为它很直观,并且提供了一组日期字符串。

          import re
          import datetime
          
          def datetime_to_str_date(dt):
              return re.sub(r'\T.+$','', dt.isoformat())
          
          start_date = datetime.datetime.strptime('2016-01-01', '%Y-%m-%d')
          end_date = datetime.datetime.today()
          num_of_days = (end_date - start_date).days
          
          date_list = map(
                  datetime_to_str_date, 
                  [start_date + datetime.timedelta(days=x) for x in range(0, num_of_days)]
          )
          

          【讨论】:

            【解决方案8】:
            >>> for a in range(9):
            ...     print(datetime.date(2011, 05, 03) + datetime.timedelta(a))
            ...
            2011-05-03
            2011-05-04
            2011-05-05
            2011-05-06
            2011-05-07
            2011-05-08
            2011-05-09
            2011-05-10
            2011-05-11
            

            我不太确定字符串的解析是完整的还是您开始问题的方式。如果是这样,请忽略答案过于简单

            【讨论】:

              【解决方案9】:
              import pandas as pd
              date1 = '2011-05-03'
              date2 = '2011-05-10'
              pd.date_range(start = date1,end = date2)
              

              【讨论】:

              • 欢迎来到 Stack Overflow!尽管我们感谢您的回答,但如果它在其他答案之上提供额外的价值会更好。在这种情况下,您的答案不会提供额外的价值,因为另一个用户已经发布了该解决方案。如果之前的答案对您有帮助,您应该投票而不是重复相同的信息。
              猜你喜欢
              • 2021-07-10
              • 2018-11-06
              • 2020-12-20
              • 2017-10-05
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多