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

Viewed 150927

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

18 Answers

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.

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}'

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

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

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

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

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))
for m in range(1, 13):
  print ((m*3)//10)

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