我想找到最接近指定日期的四分之一:例如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
答案 0 :(得分:1)
datetime.timedelta
可能为负数,diff.days <= 45
对于负时间增量始终为真,因此结果不正确。
您已经有了一个简单的解决方案,候选人到位了。这些是
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
,因为我们在出现平局时会占用当前季度。
第一个功能