Is there a function to determine which quarter of the year a date is in?

PythonDate

Python Problem Overview


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

Python Solutions


Solution 1 - Python

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

Solution 2 - Python

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

Solution 3 - Python

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.

Solution 4 - Python

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!

Solution 5 - Python

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 = f'q{(now.month-1)//3+1}'

Solution 6 - Python

if m is the month number...

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

Solution 7 - Python

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

Solution 8 - Python

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

Solution 9 - Python

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

Solution 10 - Python

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

Solution 11 - Python

I tried the solution with x//3+1 and x//4+1, We get incorrect quarter in either case. The correct answer is like this

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

Solution 12 - Python

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

Solution 13 - Python

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]

Solution 14 - Python

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

Solution 15 - Python

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

Solution 16 - Python

for m in range(1, 13):
  print ((m*3)//10)

Solution 17 - Python

A revisited solution using @Alex Martelli formula and creting a quick function as the question asks.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJason ChristaView Question on Stackoverflow
Solution 1 - PythonAlex MartelliView Answer on Stackoverflow
Solution 2 - PythonchishakuView Answer on Stackoverflow
Solution 3 - PythonJonathan RocherView Answer on Stackoverflow
Solution 4 - PythonAdam StewartView Answer on Stackoverflow
Solution 5 - PythonJavDomGomView Answer on Stackoverflow
Solution 6 - PythongarbanzioView Answer on Stackoverflow
Solution 7 - PythonSiddaram HView Answer on Stackoverflow
Solution 8 - PythonRoei BahumiView Answer on Stackoverflow
Solution 9 - PythonUri GorenView Answer on Stackoverflow
Solution 10 - PythonMikeHossView Answer on Stackoverflow
Solution 11 - PythonDeepaView Answer on Stackoverflow
Solution 12 - PythonSeenu SView Answer on Stackoverflow
Solution 13 - PythonAnurag UniyalView Answer on Stackoverflow
Solution 14 - PythonigniteflowView Answer on Stackoverflow
Solution 15 - PythonLedView Answer on Stackoverflow
Solution 16 - PythonakashView Answer on Stackoverflow
Solution 17 - PythonFederico BaùView Answer on Stackoverflow