Jason Christa
Jason Christa

Reputation: 12508

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

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

Upvotes: 163

Views: 213442

Answers (19)

MikeHoss
MikeHoss

Reputation: 1487

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

Upvotes: 2

Siddaram H
Siddaram H

Reputation: 1176

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

import pandas as pd

today_date = pd.Timestamp.today()
quarter = pd.Period(today_date, freq='Q-MAR').strftime('Q%q')

quarter == 'Q4'

reference: pandas period index

Upvotes: 5

Uri Goren
Uri Goren

Reputation: 13700

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

Upvotes: 4

Shahidul Islam Molla
Shahidul Islam Molla

Reputation: 640

Below code is working for me!

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

Output:

enter image description here

Upvotes: 2

chishaku
chishaku

Reputation: 4643

IF you are already using pandas, it's quite simple: use the .quarter attribute.

e.g. Timestamp.quarter:

import pandas as pd

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

If you have a date column in a dataframe, you can easily create a new quarter column with Series.dt.quarter:

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

Upvotes: 82

Roei Bahumi
Roei Bahumi

Reputation: 3673

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

And the output is:

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

Upvotes: 6

Igor Goldobin
Igor Goldobin

Reputation: 1

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

Upvotes: -1

Federico Baù
Federico Baù

Reputation: 7715

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

Upvotes: 1

JavDomGom
JavDomGom

Reputation: 1175

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

Upvotes: 18

Seenu S
Seenu S

Reputation: 3481

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

Upvotes: 1

Deepa
Deepa

Reputation: 11

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) 

Upvotes: 1

akash
akash

Reputation: 1

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

Upvotes: 0

Led
Led

Reputation: 517

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

Upvotes: 0

igniteflow
igniteflow

Reputation: 9782

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

Upvotes: 0

Alex Martelli
Alex Martelli

Reputation: 882123

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

Upvotes: 235

Adam Stewart
Adam Stewart

Reputation: 2149

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!

Upvotes: 16

garbanzio
garbanzio

Reputation: 846

if m is the month number...

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

Upvotes: 8

Jonathan Rocher
Jonathan Rocher

Reputation: 461

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.

Upvotes: 46

Anurag Uniyal
Anurag Uniyal

Reputation: 88827

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]

Upvotes: 0

Related Questions