【问题标题】:Determine consecutive dates确定连续日期
【发布时间】:2013-06-09 22:44:20
【问题描述】:

我有一个datetime.dates 列表,我需要检查每个日期是否来自下一个连续月份。

希望从代码中清楚我的意思:

import datetime
from unittest import TestCase


def is_consecutive(dates):
    # TODO
    return


class DatesTestCase(TestCase):
    def test_consecutive(self):
        self.assertTrue(is_consecutive([datetime.date(2010, 10, 3),
                                        datetime.date(2010, 11, 8),
                                        datetime.date(2010, 12, 1),
                                        datetime.date(2011, 01, 11)]))

    def test_not_consecutive(self):
        self.assertFalse(is_consecutive([datetime.date(2010, 7, 6),
                                         datetime.date(2010, 8, 24),
                                         datetime.date(2010, 3, 5),
                                         datetime.date(2010, 10, 25)]))

        self.assertFalse(is_consecutive([datetime.date(2010, 10, 6),
                                         datetime.date(2010, 11, 2),
                                         datetime.date(2010, 12, 9),
                                         datetime.date(2010, 01, 20)]))

你将如何实现is_consecutive

非常感谢您的帮助(建议、提示、代码或任何有用的东西)!

【问题讨论】:

    标签: python datetime python-2.x


    【解决方案1】:

    遍历列表中除最后一项之外的每一项,并将其与下一项进行比较。如果第二个的月份正好比第一个的月份大一个,或者如果第二个的月份是 1 并且第二个的年份正好比第一个的年份大一个,则两个项目是连续的。第一次失败返回False,否则最后返回True

    编辑:在第二种情况下,显然第一个的月份必须是 12,除了第二个的月份是 1。代码已更新。

    编辑 2:在第一种情况下,显然年份应该相同。这就是你写得太快的结果。

    先例:

    #!/usr/bin/python
    
    from datetime import date
    
    def is_consecutive(datelist):
        for idx, my_date in enumerate(datelist[:-1]):
            if ((datelist[idx + 1].month - my_date.month == 1 and
                 datelist[idx + 1].year == my_date.year) or
                (datelist[idx + 1].month == 1 and
                 my_date.month == 12 and
                 datelist[idx + 1].year - my_date.year == 1)):
                continue
            else:
                return False
        return True
    
    print is_consecutive([date(2010, 10, 3),
                          date(2010, 11, 8),
                          date(2010, 12, 1),
                          date(2011, 1, 11)])
    
    print is_consecutive([date(2010, 7, 6),
                          date(2010, 8, 24),
                          date(2010, 3, 5),
                          date(2010, 10, 25)])
    

    另一种实现,可能更容易遵循,但基本上做同样的事情:

    def is_consecutive(datelist):
        for idx, my_date in enumerate(datelist[:-1]):
            month_diff = datelist[idx + 1].month - my_date.month
            year_diff = datelist[idx + 1].year - my_date.year
            if ((month_diff == 1 and year_diff == 0) or
                (month_diff == -11 and year_diff == 1)):
                continue
            else:
                return False
        return True
    

    【讨论】:

      【解决方案2】:

      这适用于您的示例,并且应该可以正常工作:

      def is_consecutive(data):
          dates=data[:]
          while len(dates)>1:
              d2=dates.pop().replace(day=1)
              d1=dates[-1].replace(day=1)
              d3=d1+datetime.timedelta(days=32)
              if d3.month!=d2.month or d3.year!=d2.year:
                  return False        
          return True
      

      【讨论】:

      • 对于像 [date(2010,9,3), date(2010, 10, 8), date(2010, 12, 1), date(2011, 1, 11)] 其中第二个和第三个日期不连续。我认为您可能应该将其中一个日期推回列表中,否则您将匹配成对的日期,而不是每对与下一个是否连续。
      • @PaulGriffiths:是的,你是对的。我是成对地而不是串行地获取数据。固定
      【解决方案3】:

      这是解决此问题的另一种方法:

      def is_consecutive(dates):
          months =  [date.month for date in sorted(dates)]  # extracting months from date, dates list has to be sorted first
          months_diff = [abs(x - months[i - 1]) for i, x in enumerate(months) if i>0]  # creates a resulting list of values after subtracting month with a previous month (absolute value is needed to account for the case when subtracting December(12) from January(1)
          if not(set(months_diff) - set([1,11])):  # if months_diff contains any values other than 11 and 1 then dates are not consecutive
               return True
          return False
      

      【讨论】:

        猜你喜欢
        • 2021-08-19
        • 1970-01-01
        • 2018-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-08
        相关资源
        最近更新 更多