是否有一个函数来确定日期在一年的哪个季度?

当然,我可以自己编写这个函数,但是在我开始重造轮子之前,是否有一个函数已经做到了这一点?

159277 次浏览

给定一个 xDatetime.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模块,用于在工作中使用我的(和其他人的)项目,它有许多小函数来执行所有这些日历计算——有些很复杂,有些很简单,但没有理由一遍又一遍地做这些工作(即使是简单的工作) ,或者在这样的计算中存在 bug; ——)。

嗯,所以计算可能会出错,这里有一个更好的版本(只是为了它的缘故)

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]

我会提出另一个可以说是更干净的解决方案。如果 X 是一个 datetime.datetime.now()实例,那么这个季度是:

import math
Q=math.ceil(X.month/3.)

Ceil 必须从数学模块导入,因为它不能被直接访问。

这是一个老问题,但仍值得讨论。

这是我的解决方案,使用优秀的 约会模块。

  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是本季度的最后一天(计算方法是找出下一季度的第一天,减去一天)。

如果 m是月号..。

import math
math.ceil(float(m) / 3)

如果您已经使用了 pandas,那么它非常简单。

import datetime as dt
import pandas as pd


quarter = pd.Timestamp(dt.date(2016, 2, 29)).quarter
assert quarter == 1

如果你在数据框架中有一个 date列,你可以很容易地创建一个新的 quarter列:

df['quarter'] = df['date'].dt.quarter

对于任何试图获得 财政年的季度(可能不同于 日历年)的人,我编写了一个 Python 模块来完成这项工作。

安装很简单,只需运行:

$ pip install fiscalyear

没有依赖关系,而且 fiscalyear应该可以同时适用于 Python2和3。

它基本上是一个内置 日期时间模块的包装器,所以任何您已经熟悉的 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托管在 GitHubPyPI上。文档可以在 看看文件找到。如果您正在寻找任何功能,它目前没有,让我知道!

下面是一个详细但可读的解决方案,可用于日期时和日期实例

def get_quarter(date):
for months, quarter in [
([1, 2, 3], 1),
([4, 5, 6], 2),
([7, 8, 9], 3),
([10, 11, 12], 4)
]:
if date.month in months:
return quarter

对于那些寻找财政年度季度数据的人来说, 用熊猫,

import datetime
import pandas as pd
today_date = datetime.date.today()
quarter = pd.PeriodIndex(today_date, freq='Q-MAR').strftime('Q%q')

参考文献: 大熊猫周期指数

这种方法适用于任何映射:

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

下面是一个函数的示例,该函数获取 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

使用字典,你可以通过

def get_quarter(month):
quarter_dictionary = {
"Q1" : [1,2,3],
"Q2" : [4,5,6],
"Q3" : [7,8,9],
"Q4" : [10,11,12]
}


for key,values in quarter_dictionary.items():
for value in values:
if value == month:
return key


print(get_quarter(3))

这非常简单,可以在 python3中使用:

from datetime import datetime


# Get current date-time.
now = datetime.now()


# Determine which quarter of the year is now. Returns q1, q2, q3 or q4.
quarter_of_the_year = f'q{(now.month-1)//3+1}'
for m in range(1, 13):
print ((m*3)//10)

我用 x//3 + 1和 x//4 + 1试过了, 不管哪种情况,我们都得到了错误的季度。 正确答案是这样的

for i in range(1,13):
print(((i-1)//3)+1)
import datetime


def get_quarter_number_and_date_from_choices(p_quarter_choice):
"""
:param p_quarter_choice:
:return:
"""


current_date = datetime.date.today()
# current_quarter = current_date.month - 1 // 3 + 1
if p_quarter_choice == 'Q1':
quarter = 1
q_start_date = datetime.datetime(current_date.year, 3 * quarter - 2, 1)
q_end_date = datetime.datetime(current_date.year, 3 * quarter + 1, 1) + datetime.timedelta(days=-1)
return q_start_date, q_end_date
elif p_quarter_choice == 'Q2':
quarter = 2
q_start_date = datetime.datetime(current_date.year, 3 * quarter - 2, 1)
q_end_date = datetime.datetime(current_date.year, 3 * quarter + 1, 1) + datetime.timedelta(days=-1)
return q_start_date, q_end_date
elif p_quarter_choice == 'Q3':
quarter = 3
q_start_date = datetime.datetime(current_date.year, 3 * quarter - 2, 1)
q_end_date = datetime.datetime(current_date.year, 3 * quarter + 1, 1) + datetime.timedelta(days=-1)
return q_start_date, q_end_date
elif p_quarter_choice == 'Q4':
quarter = 4
q_start_date = datetime.datetime(current_date.year, 3 * quarter - 2, 1)
q_end_date = datetime.datetime(current_date.year, 3 * quarter, 1) + datetime.timedelta(days=30)
return q_start_date, q_end_date
return None

使用@Alex Martelli 公式重新访问解决方案,并在问题提出时创建一个快速函数。

from datetime import timedelta, date


date_from = date(2021, 1, 1)
date_to = date(2021, 12, 31)


get_quarter = lambda dt: (dt.month-1)//3 + 1


quarter_from = get_quarter(date_from)
quarter_to = get_quarter(date_to)
print(quarter_from)
print(quarter_to)
# 1
# 4
def euclid(a,b):
r = a % b
q = int(  ( (a + b - 1) - (a - 1) % b ) / b  )
return(q,r)


months_per_year = 12
months_per_quarter = 3


for i in range(months_per_year):
print(i+1,euclid(i+1,months_per_quarter)[0])


#1 1
#2 1
#3 1
#4 2
#5 2
#6 2
#7 3
#8 3
#9 3
#10 4
#11 4
#12 4