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

问题:是否有Python函数可确定日期在一年的哪个季度?

当然,我可以自己写这个,但是在我重新发明轮子之前,已经有一个已经做到这一点的功能了吗?

Sure I could write this myself, but before I go reinventing the wheel is there a function that already does this?


回答 0

给定一个实例xdatetime.date(x.month-1)//3会给你的四分之一(0第一季度,1第二季度,等等-加1,如果你需要从1计数,而不是;-)。


最初有两个答案,乘以赞成票,甚至最初被接受(目前都已删除),但有很多错误- -1除法前不做除法,而是除以4而不是3。从.month1到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模块来使用我的(以及其他人)项目,该模块几乎没有执行所有这些日历计算的函数-有些复杂,有些简单,但没有理由一遍又一遍地进行工作(甚至是简单的工作),也没有理由冒这样的错误;-)。

Given an instance x of datetime.date, (x.month-1)//3 will give you the quarter (0 for first quarter, 1 for second quarter, etc — add 1 if you need to count from 1 instead;-).


Originally two answers, multiply upvoted and even originally accepted (both currently deleted), were buggy — not doing the -1 before the division, and dividing by 4 instead of 3. Since .month goes 1 to 12, it’s easy to check for yourself what formula is right:

for m in range(1, 13):
  print m//4 + 1,
print

gives 1 1 1 2 2 2 2 3 3 3 3 4 — two four-month quarters and a single-month one (eep).

for m in range(1, 13):
  print (m-1)//3 + 1,
print

gives 1 1 1 2 2 2 3 3 3 4 4 4 — now doesn’t this look vastly preferable to you?-)

This proves that the question is well warranted, I think;-).

I don’t think the datetime module should necessarily have every possible useful calendric function, but I do know I maintain a (well-tested;-) datetools module for the use of my (and others’) projects at work, which has many little functions to perform all of these calendric computations — some are complex, some simple, but there’s no reason to do the work over and over (even simple work) or risk bugs in such computations;-).


回答 1

如果您已经在使用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

IF you are already using pandas, it’s quite simple.

import datetime as dt
import pandas as pd

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

If you have a date column in a dataframe, you can easily create a new quarter column:

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

回答 2

我会建议另一个可以说更清洁的解决方案。如果X是一个datetime.datetime.now()实例,则四分之一是:

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

必须从数学模块中导入ceil,因为它无法直接访问。

I would suggest another arguably cleaner solution. If X is a datetime.datetime.now() instance, then the quarter is:

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

ceil has to be imported from math module as it can’t be accessed directly.


回答 3

对于试图获取会计年度季度(可能与日历年度有所不同)的任何人,我都编写了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托管在GitHubPyPI上。可以在“ 阅读文档”中找到文档。如果您正在寻找它当前没有的任何功能,请告诉我!

For anyone trying to get the quarter of the fiscal year, which may differ from the calendar year, I wrote a Python module to do just this.

Installation is simple. Just run:

$ pip install fiscalyear

There are no dependencies, and fiscalyear should work for both Python 2 and 3.

It’s basically a wrapper around the built-in datetime module, so any datetime commands you are already familiar with will work. Here’s a demo:

>>> 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 is hosted on GitHub and PyPI. Documentation can be found at Read the Docs. If you’re looking for any features that it doesn’t currently have, let me know!


回答 4

这是一个获取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

Here is an example of a function that gets a datetime.datetime object and returns a unique string for each quarter:

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))

And the output is:

2019-02-14 Q1_2019
2018-11-16 Q4_2018
2017-08-18 Q3_2017

回答 5

如果m是月份号…

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

if m is the month number…

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

回答 6

此方法适用于任何映射:

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

This method works for any mapping:

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

We have just generated a function int->int

month2quarter(9) # returns 3

This method is also fool-proof

month2quarter(-1) # returns None
month2quarter('July') # returns None

回答 7

对于那些正在使用熊猫查询会计年度季度数据的人,

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

参考: 大熊猫时期指数

For those, who are looking for financial year quarter data, using pandas,

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

reference: pandas period index


回答 8

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

这是我的解决方案,使用了出色的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的最后一天(通过找到下一个季度的第一天减去一天来计算)。

This is an old question but still worthy of discussion.

Here is my solution, using the excellent dateutil module.

  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)

So first_day is the first day of the quarter, and last_day is the last day of the quarter (calculated by finding the first day of the next quarter, minus one day).


回答 9

这非常简单,可以在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 = 'q'+str((now.month-1)//3+1)

This is very simple and works in 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 = 'q'+str((now.month-1)//3+1)

回答 10

嗯,所以计算可能会出错,这是一个更好的版本(仅出于此目的)

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]

hmmm so calculations can go wrong, here is a better version (just for the sake of it)

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]

回答 11

这是一个冗长但易读的解决方案,适用于datetime和date实例

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

Here is a verbose, but also readable solution that will work for datetime and date instances

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

回答 12

使用字典,您可以通过

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))

using dictionaries, you can pull this off by

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))