【问题标题】:How to increment a datetime by one day?如何将日期时间增加一天?
【发布时间】:2011-03-15 12:05:44
【问题描述】:

如何增加日期时间的天数?

for i in range(1, 35)
    date = datetime.datetime(2003, 8, i)
    print(date)

但我需要正确地度过几个月和几年?有什么想法吗?

【问题讨论】:

    标签: python datetime


    【解决方案1】:
    date = datetime.datetime(2003,8,1,12,4,5)
    for i in range(5): 
        date += datetime.timedelta(days=1)
        print(date) 
    

    【讨论】:

    【解决方案2】:

    可以使用 timedelta 对象来增加日期:

    import datetime
    
    datetime.datetime.now() + datetime.timedelta(days=1)
    

    在 Python 文档中查找 timedelta 对象:http://docs.python.org/library/datetime.html

    【讨论】:

      【解决方案3】:

      这是另一种使用 dateutil 的 relativedelta 添加日期的方法。

      from datetime import datetime
      from dateutil.relativedelta import relativedelta
      
      print 'Today: ',datetime.now().strftime('%d/%m/%Y %H:%M:%S') 
      date_after_month = datetime.now()+ relativedelta(day=1)
      print 'After a Days:', date_after_month.strftime('%d/%m/%Y %H:%M:%S')
      

      输出:

      今天:25/06/2015 20:41:44

      一天之后:01/06/2015 20:41:44

      【讨论】:

      • 为什么要使用它而不是 stdlib 中的timedelta()
      • @J.F.Sebastian 只是为了分享另一种可能的方式来增加一天。
      • 如果没有优势,我认为它不会增加价值。
      【解决方案4】:

      在某些情况下,所有当前的答案都是错误的,因为他们不认为时区会改变它们相对于 UTC 的偏移量。因此,在某些情况下,添加 24 小时与添加日历日是不同的。

      建议的解决方案

      以下解决方案适用于萨摩亚并保持本地时间不变。

      def add_day(today):
          """
          Add a day to the current day.
      
          This takes care of historic offset changes and DST.
      
          Parameters
          ----------
          today : timezone-aware datetime object
      
          Returns
          -------
          tomorrow : timezone-aware datetime object
          """
          today_utc = today.astimezone(datetime.timezone.utc)
          tz = today.tzinfo
          tomorrow_utc = today_utc + datetime.timedelta(days=1)
          tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
          tomorrow_utc_tz = tomorrow_utc_tz.replace(hour=today.hour,
                                                    minute=today.minute,
                                                    second=today.second)
          return tomorrow_utc_tz
      

      测试代码

      # core modules
      import datetime
      
      # 3rd party modules
      import pytz
      
      
      # add_day methods
      def add_day(today):
          """
          Add a day to the current day.
      
          This takes care of historic offset changes and DST.
      
          Parameters
          ----------
          today : timezone-aware datetime object
      
          Returns
          -------
          tomorrow : timezone-aware datetime object
          """
          today_utc = today.astimezone(datetime.timezone.utc)
          tz = today.tzinfo
          tomorrow_utc = today_utc + datetime.timedelta(days=1)
          tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
          tomorrow_utc_tz = tomorrow_utc_tz.replace(hour=today.hour,
                                                    minute=today.minute,
                                                    second=today.second)
          return tomorrow_utc_tz
      
      
      def add_day_datetime_timedelta_conversion(today):
          # Correct for Samoa, but dst shift
          today_utc = today.astimezone(datetime.timezone.utc)
          tz = today.tzinfo
          tomorrow_utc = today_utc + datetime.timedelta(days=1)
          tomorrow_utc_tz = tomorrow_utc.astimezone(tz)
          return tomorrow_utc_tz
      
      
      def add_day_dateutil_relativedelta(today):
          # WRONG!
          from dateutil.relativedelta import relativedelta
          return today + relativedelta(days=1)
      
      
      def add_day_datetime_timedelta(today):
          # WRONG!
          return today + datetime.timedelta(days=1)
      
      
      # Test cases
      def test_samoa(add_day):
          """
          Test if add_day properly increases the calendar day for Samoa.
      
          Due to economic considerations, Samoa went from 2011-12-30 10:00-11:00
          to 2011-12-30 10:00+13:00. Hence the country skipped 2011-12-30 in its
          local time.
      
          See https://stackoverflow.com/q/52084423/562769
      
          A common wrong result here is 2011-12-30T23:59:00-10:00. This date never
          happened in Samoa.
          """
          tz = pytz.timezone('Pacific/Apia')
          today_utc = datetime.datetime(2011, 12, 30, 9, 59,
                                        tzinfo=datetime.timezone.utc)
          today_tz = today_utc.astimezone(tz)  # 2011-12-29T23:59:00-10:00
          tomorrow = add_day(today_tz)
          return tomorrow.isoformat() == '2011-12-31T23:59:00+14:00'
      
      
      def test_dst(add_day):
          """Test if add_day properly increases the calendar day if DST happens."""
          tz = pytz.timezone('Europe/Berlin')
          today_utc = datetime.datetime(2018, 3, 25, 0, 59,
                                        tzinfo=datetime.timezone.utc)
          today_tz = today_utc.astimezone(tz)  # 2018-03-25T01:59:00+01:00
          tomorrow = add_day(today_tz)
          return tomorrow.isoformat() == '2018-03-26T01:59:00+02:00'
      
      
      to_test = [(add_day_dateutil_relativedelta, 'relativedelta'),
                 (add_day_datetime_timedelta, 'timedelta'),
                 (add_day_datetime_timedelta_conversion, 'timedelta+conversion'),
                 (add_day, 'timedelta+conversion+dst')]
      print('{:<25}: {:>5} {:>5}'.format('Method', 'Samoa', 'DST'))
      for method, name in to_test:
          print('{:<25}: {:>5} {:>5}'
                .format(name,
                        test_samoa(method),
                        test_dst(method)))
      

      测试结果

      Method                   : Samoa   DST
      relativedelta            :     0     0
      timedelta                :     0     0
      timedelta+conversion     :     1     0
      timedelta+conversion+dst :     1     1
      

      【讨论】:

      • 其他答案并非完全错误,在使用 UTC 或天真 (tzinfo == None) 日期时间时它们完全没问题。
      【解决方案5】:

      这对我来说是一个简单的解决方案:

      from datetime import timedelta, datetime
      
      today = datetime.today().strftime("%Y-%m-%d")
      tomorrow = datetime.today() + timedelta(1)
      
      

      【讨论】:

      • 这不直接回答 OP 问题,因为它假定 today() 并且不如接受的答案好,因为它假定默认增量单位是 days
      • @MarkHu 我并不是说我的答案应该被接受。但是您能否详细说明today() 的假设是什么以及为什么这是一个错误的假设?也不是问了几天的问题吗?接受的答案是否更普遍?
      • 1. OP询问如何在任意日期之后找到第二天,而不是今天。您的示例代码将名为 today 的变量分配为字符串,然后从未使用它。更好:date = datetime.today() 2. 你的最后一行硬编码today() 并假设timedelta 的第一个参数是days(这恰好是正确的,但为什么不为清楚起见命名呢?)更好:laterDate = date + timedelta(days=1) # 恕我直言:)
      【解决方案6】:

      最简单的解决方案

      from datetime import timedelta, datetime
      date = datetime(2003,8,1,12,4,5)
      for i in range(5):
          date += timedelta(days=1)
          print(date)
      

      【讨论】:

        【解决方案7】:

        您还可以导入 timedelta 以使代码更简洁。

        from datetime import datetime, timedelta
        date = datetime.now() + timedelta(seconds=[delta_value])
        

        然后将日期转为字符串

        date = date.strftime('%Y-%m-%d %H:%M:%S')
        

        Python 单线是

        date = (datetime.now() + timedelta(seconds=[delta_value])).strftime('%Y-%m-%d %H:%M:%S')
        

        【讨论】:

          【解决方案8】:

          根本没有库的简短解决方案。 :)

          d = "8/16/18"
          day_value = d[(d.find('/')+1):d.find('/18')]
          tomorrow = f"{d[0:d.find('/')]}/{int(day_value)+1}{d[d.find('/18'):len(d)]}".format()
          print(tomorrow)
          # 8/17/18
          

          确保“string d”实际上是%m/%d/%Y 的形式,这样您就不会在从一个月过渡到下一个月时遇到问题。

          【讨论】:

          • 如果将d 设置为8/31/18,则返回8/32/18。如果您将年份从18 更改,它就会中断。
          猜你喜欢
          • 2018-02-06
          • 1970-01-01
          • 2019-02-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多