当然,我可以自己写这个,但是在我重新发明轮子之前,已经有一个已经做到这一点的功能了吗?
当然,我可以自己写这个,但是在我重新发明轮子之前,已经有一个已经做到这一点的功能了吗?
Answers:
给定一个实例x
的datetime.date,(x.month-1)//3
会给你的四分之一(0第一季度,1第二季度,等等-加1,如果你需要从1计数,而不是;-)。
最初有两个答案,乘以赞成票,甚至最初被接受(目前都已删除),但有很多错误- -1
除法前不做除法,而是除以4而不是3。从.month
1到12,可以很容易地检查一下自己的公式是什么对:
for m in range(1, 13):
print m//4 + 1,
print
给出1 1 1 2 2 2 2 3 3 3 3 4
-两个四个月的季度和一个月的季度(深度)。
for m in range(1, 13):
print (m-1)//3 + 1,
print
给1 1 1 2 2 2 3 3 3 4 4 4
-现在看起来这对您来说不是很可取吗?-)
我认为,这证明了这个问题是正确的;-)。
我认为datetime模块不一定应该具有所有可能有用的日历功能,但是我确实知道我在工作中维护了一个(经过测试;-)datetools
模块来使用我的(以及其他人)项目,该模块几乎没有执行所有这些日历计算的函数-有些复杂,有些简单,但没有理由一遍又一遍地进行工作(甚至是简单的工作),也没有理由冒这样的错误;-)。
(m+2)//3
代替(m-1)//3 + 1
我会建议另一个可以说更清洁的解决方案。如果X是一个datetime.datetime.now()
实例,则四分之一是:
import math
Q=math.ceil(X.month/3.)
必须从数学模块中导入ceil,因为它无法直接访问。
math.ceil(float(4)/3) = 2.0
math.ceil(4/3) = 1.0
.
3之后的情况。math.ceil(4/3.) = 2.0
对于试图获取会计年度季度(可能与日历年度有所不同)的任何人,我都编写了Python模块来执行此操作。
安装很简单。赶紧跑:
$ pip install fiscalyear
没有依赖关系,并且fiscalyear
对Python 2和3都适用。
它基本上是内置的datetime模块的包装器,因此,datetime
您已经熟悉的任何命令都可以使用。这是一个演示:
>>> from fiscalyear import *
>>> a = FiscalDate.today()
>>> a
FiscalDate(2017, 5, 6)
>>> a.fiscal_year
2017
>>> a.quarter
3
>>> b = FiscalYear(2017)
>>> b.start
FiscalDateTime(2016, 10, 1, 0, 0)
>>> b.end
FiscalDateTime(2017, 9, 30, 23, 59, 59)
>>> b.q3
FiscalQuarter(2017, 3)
>>> b.q3.start
FiscalDateTime(2017, 4, 1, 0, 0)
>>> b.q3.end
FiscalDateTime(2017, 6, 30, 23, 59, 59)
fiscalyear
托管在GitHub和PyPI上。可以在“ 阅读文档”中找到文档。如果您正在寻找它当前没有的任何功能,请告诉我!
这是一个获取datetime.datetime对象并为每个季度返回唯一字符串的函数示例:
from datetime import datetime, timedelta
def get_quarter(d):
return "Q%d_%d" % (math.ceil(d.month/3), d.year)
d = datetime.now()
print(d.strftime("%Y-%m-%d"), get_q(d))
d2 = d - timedelta(90)
print(d2.strftime("%Y-%m-%d"), get_q(d2))
d3 = d - timedelta(180 + 365)
print(d3.strftime("%Y-%m-%d"), get_q(d3))
输出为:
2019-02-14 Q1_2019
2018-11-16 Q4_2018
2017-08-18 Q3_2017
此方法适用于任何映射:
month2quarter = {
1:1,2:1,3:1,
4:2,5:2,6:2,
7:3,8:3,9:3,
10:4,11:4,12:4,
}.get
我们刚刚生成了一个函数 int->int
month2quarter(9) # returns 3
这种方法也是万无一失的
month2quarter(-1) # returns None
month2quarter('July') # returns None
这是一个老问题,但仍然值得讨论。
这是我的解决方案,使用了出色的dateutil模块。
from dateutil import rrule,relativedelta
year = this_date.year
quarters = rrule.rrule(rrule.MONTHLY,
bymonth=(1,4,7,10),
bysetpos=-1,
dtstart=datetime.datetime(year,1,1),
count=8)
first_day = quarters.before(this_date)
last_day = (quarters.after(this_date)
-relativedelta.relativedelta(days=1)
因此first_day
,该季度的第一天也是该季度last_day
的最后一天(通过找到下一个季度的第一天减去一天来计算)。
嗯,所以计算可能会出错,这是一个更好的版本(仅出于此目的)
first, second, third, fourth=1,2,3,4# you can make strings if you wish :)
quarterMap = {}
quarterMap.update(dict(zip((1,2,3),(first,)*3)))
quarterMap.update(dict(zip((4,5,6),(second,)*3)))
quarterMap.update(dict(zip((7,8,9),(third,)*3)))
quarterMap.update(dict(zip((10,11,12),(fourth,)*3)))
print quarterMap[6]
"it is difficult to see correctness except by testing it"
。您应该像所有优秀的开发人员一样编写测试。测试可以帮助您避免犯错,并发现错误。开发人员切勿牺牲性能和可读性,以防止自己犯错。而且,这比您仅使用文字量编写静态字典时的可读性差。
(m-1)//3 + 1
是全部可读,没有多少人知道它是什么//
。我最初的评论只是对我的说法"calculations can go wrong"
听起来有些奇怪。