查找最近的季度结束日期?

时间:2015-09-07 18:58:21

标签: python python-2.7

我想找到最接近指定日期的四分之一:例如2014年5月27日最接近的季度末将是6/30/2014,2013年2月2日将是12/31/2012。我有以下内容,但它没有给我2015年8月15日这样的日期的预期输出:

import datetime

tester = datetime.datetime(2015, 8, 15)

calendar_date = datetime.datetime(tester.year - 1, 12, 31)
for dd in [(3, 31), (6, 30), (9, 30), (12, 31)]:
    diff = abs(datetime.datetime(tester.year, dd[0], dd[1]) - tester)
    if diff.days <= 45:
        calendar_date = datetime.datetime(tester.year, dd[0], dd[1])
        break

print tester, calendar_date

我简化了假设每个​​季度是90天,因此在45天时取出1/2(有更好的方法吗?)但显然这对于​​2015年8月16日不起作用它打印:

2015-08-15 00:00:00 2014-12-31 00:00:00

我期待2015-09-30 00:00:00

2 个答案:

答案 0 :(得分:1)

datetime.timedelta可能为负数,diff.days <= 45对于负时间增量始终为真,因此结果不正确。

您已经有了一个简单的解决方案,候选人到位了。这些是

  1. 目标日期前一年的最后一个季度
  2. 本年度的所有四个季度
  3. datetime.timedelta个对象具有相对比较运算符,即它们形成一个总顺序,这意味着它是最小的。如Padraic Cunningham的评论中所述,您希望候选人的最小绝对距离达到目标日期:

    def get_closest_quarter(target):
        # candidate list, nicely enough none of these 
        # are in February, so the month lengths are fixed
        candidates = [
            datetime.date(target.year - 1, 12, 31),
            datetime.date(target.year, 3, 31),
            datetime.date(target.year, 6, 30),
            datetime.date(target.year, 9, 30),
            datetime.date(target.year, 12, 31),
        ]
        # take the minimum according to the absolute distance to
        # the target date.
        return min(candidates, key=lambda d: abs(target - d))
    

    此处的代码使用datetime.date来简化,但如果需要,应该很容易概括为datetime.datetime

答案 1 :(得分:1)

您可以使用ind = (dt.month-1) // 3 + 1来比较两个日期,以获取当前季度的索引:

def find_qrt(dt):
    qrts = [date(dt.year - 1, 12, 31), date(dt.year, 3, 31),
            date(dt.year, 6, 30), date(dt.year, 9, 30),
            date(dt.year, 12, 31),
            ]
    ind = (dt.month-1) // 3 + 1
    curr_qr, last_qr = qrts[ind], qrts[ind-1]
    return curr_qr if abs(curr_qr - dt) < abs(last_qr - dt) else last_qr

如果您想根据示例日期返回后一季度,我们只需要使用<=

dt = datetime.date(2015, 8, 15)
from datetime import date

def find_qrt(dt):
    qrts = [date(dt.year - 1, 12, 31), date(dt.year, 3, 31),
            date(dt.year, 6, 30), date(dt.year, 9, 30),
            date(dt.year, 12, 31),
            ]
    ind = (dt.month-1) // 3 + 1
    curr_qr, last_qr = qrts[ind],qrts[ind-1]
    return curr_qr if abs(curr_qr - dt) <= abs(last_qr - dt) else last_qr

print(find_qrt(dt))

第一个函数将返回2015-06-30,因为较早的日期会打破平局,第二个函数会得到2015-09-30,因为我们在出现平局时会占用当前季度。

第一个功能