是否有一个函数可以确定某个日期位于一年中的哪个季度?
- 2025-04-16 08:58:00
- admin 原创
- 19
问题描述:
当然我可以自己写这个,但是在我重新发明轮子之前是否有一个函数可以做到这一点?
解决方案 1:
给定datetime.datex
的一个实例,将为您提供季度(0 代表第一季度,1 代表第二季度,等等 - 如果您需要从 1 开始计数,则加 1;-)。(x.month-1)//3
最初的两个答案,被多次赞成,甚至最初被接受(目前都已被删除),都是有缺陷的——在-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
——两个四个月的季度和一个单月的季度(eep)。
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
模块供我(和其他人)在工作中的项目使用,它有许多小功能来执行所有这些日历计算 - 有些很复杂,有些很简单,但没有理由一遍又一遍地做这些工作(即使是简单的工作)或冒着此类计算中出现错误的风险;-)。
解决方案 2:
如果您已经在使用pandas
,那么很简单:使用.quarter
属性。
例如Timestamp.quarter
:
import pandas as pd
quarter = pd.Timestamp(2016, 2, 29).quarter
assert quarter == 1
如果数据框中有一个日期列,则可以轻松创建一个新的季度列Series.dt.quarter
:
df['quarter'] = df['date'].dt.quarter
解决方案 3:
我建议另一个更简洁的解决方案。如果 X 是一个datetime.datetime.now()
实例,那么季度就是:
import math
Q=math.ceil(X.month/3.)
ceil 必须从数学模块导入,因为它不能直接访问。
解决方案 4:
这非常简单并且在 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}'
解决方案 5:
对于那些试图获取财政年度季度(可能与日历年不同)的人来说,我编写了一个 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上。文档可在阅读文档中找到。如果您正在寻找任何它目前尚不支持的功能,请告诉我!
解决方案 6:
如果m
是月份数...
import math
math.ceil(float(m) / 3)
解决方案 7:
下面是一个函数示例,该函数获取 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_quarter(d))
d2 = d - timedelta(90)
print(d2.strftime("%Y-%m-%d"), get_quarter(d2))
d3 = d - timedelta(180 + 365)
print(d3.strftime("%Y-%m-%d"), get_quarter(d3))
输出为:
2019-02-14 Q1_2019
2018-11-16 Q4_2018
2017-08-18 Q3_2017
解决方案 8:
对于那些正在寻找财政年度季度数据的人来说,使用熊猫,
import pandas as pd
today_date = pd.Timestamp.today()
quarter = pd.Period(today_date, freq='Q-MAR').strftime('Q%q')
quarter == 'Q4'
参考:
pandas 周期索引
解决方案 9:
此方法适用于任何映射:
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
解决方案 10:
下面的代码对我有用!
df_test['Quarter'] = pd.PeriodIndex(df_test['DATE'], freq='Q')
df_test['Qtr'] = pddf_test['Quarter'].strftime('Q%q')
df_test['Day'] = pd.PeriodIndex(df_test['DATE'], freq='D').day
df_test = df_test[df_test['Day'] == 2].sort_values('DATE')
df_test
输出:
解决方案 11:
这是我的解决方案,使用优秀的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)
Sofirst_day
是该季度的第一天,last_day
是该季度的最后一天(通过找到下一个季度的第一天减一天来计算)。
解决方案 12:
我尝试了 x//3+1 和 x//4+1 的解法,但两种情况下得到的四分之一都不正确。正确答案如下
for i in range(1,13):
print(((i-1)//3)+1)
解决方案 13:
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
解决方案 14:
使用@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
解决方案 15:
嗯,计算可能会出错,这里有一个更好的版本(只是为了它)
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]
解决方案 16:
这是一个详细但易读的解决方案,适用于日期时间和日期实例
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
解决方案 17:
使用字典,你可以这样做
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))
解决方案 18:
for m in range(1, 13):
print ((m*3)//10)
解决方案 19:
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
扫码咨询,免费领取项目管理大礼包!