11

How can i get the Current Quarter year and then First Date and last Date of Current Quarter Year in Python?

i want by importing datetime

import datetime

People look into Stack overflow need straight forward answer and which should be very simple. Which ever link you provided it having lot of Comments. SO, users has to go through all the comments to find correct answer. I am writing simple and straight forward answer.

Krishh
  • 680
  • 1
  • 6
  • 19
  • 4
    Possible duplicate of [Python get first and last day of current calendar quarter](http://stackoverflow.com/questions/36793381/python-get-first-and-last-day-of-current-calendar-quarter) – piyushj May 10 '16 at 10:36
  • Thanks piyush jaiswal, when ever i searched for this, i didn't get it in first page. So, i thought its not there in stackoverflow. – Krishh May 10 '16 at 13:08

8 Answers8

20

I believe that none of the current answers are still valid in Python 3, so since this is the top hit in google for first and last day of quarter, I will provide a solution that works in Python 3 (mostly Ahmet's with // instead of /):

from datetime import date as date_class
from datetime import timedelta, datetime


def get_quarter(p_date: date_class) -> int:
    return (p_date.month - 1) // 3 + 1


def get_first_day_of_the_quarter(p_date: date_class):
    return datetime(p_date.year, 3 * ((p_date.month - 1) // 3) + 1, 1)


def get_last_day_of_the_quarter(p_date: date_class):
    quarter = get_quarter(p_date)
    return datetime(p_date.year + 3 * quarter // 12, 3 * quarter % 12 + 1, 1) + timedelta(days=-1)


assert get_quarter(datetime(year=2021, month=10, day=5).date()) == 4
assert get_quarter(datetime(year=2020, month=9, day=25).date()) == 3
assert get_quarter(datetime(year=2020, month=12, day=11).date()) == 4
assert get_quarter(datetime(year=2020, month=1, day=2).date()) == 1

assert get_first_day_of_the_quarter(datetime(2020, 10, 5).date()) == datetime(2020, 10, 1)
assert get_first_day_of_the_quarter(datetime(2020, 9, 25).date()) == datetime(2020, 7, 1)
assert get_first_day_of_the_quarter(datetime(2020, 12, 11).date()) == datetime(2020, 10, 1)
assert get_first_day_of_the_quarter(datetime(2020, 1, 2).date()) == datetime(2020, 1, 1)

assert get_last_day_of_the_quarter(datetime(2020, 10, 5).date()) == datetime(2020, 12, 31)
assert get_last_day_of_the_quarter(datetime(2020, 9, 25).date()) == datetime(2020, 9, 30)
assert get_last_day_of_the_quarter(datetime(2020, 12, 11).date()) == datetime(2020, 12, 31)
assert get_last_day_of_the_quarter(datetime(2020, 1, 2).date()) == datetime(2020, 3, 31)
assert get_last_day_of_the_quarter(datetime(2020, 5, 6).date()) == datetime(2020, 6, 30)
Peter
  • 501
  • 5
  • 14
  • 2
    get_first_day_of_the_quarter doesn't work, it returns the quarter as the month, which is wrong. It should return the ((quarter-1) * 3) +1 So if the current month is 11, that gives (4-1) * 3 + 1 which is 10 (which is the correct month for the start of the 4th quarter) – Mister Bee Nov 25 '19 at 10:37
  • right, I've fixed that (some time ago but I figured I should explicitly write a comment to state that it is now correct) – Peter Nov 24 '20 at 15:54
7

Having the first day is the same with @Karishh's solution. But, for the last date, Python2.7 causes a problem for fourth quarter. Because 12+1=13 and datetime does not accept 13 as a month. So you need to do some tricks to handle it.

import datetime


def get_quarter(date):
    return (date.month - 1) / 3 + 1

def get_first_day_of_the_quarter(date):
    quarter = get_quarter(date)
    return datetime.datetime(date.year, 3 * quarter - 2, 1)

def get_last_day_of_the_quarter(date):
    quarter = get_quarter(date)
    month = 3 * quarter
    remaining = month / 12
    return datetime.datetime(date.year + remaining, month % 12 + 1, 1) + datetime.timedelta(days=-1)
Ahmet DAL
  • 4,445
  • 9
  • 47
  • 71
  • 5
    this could also throw a `TypeError` exception. Your function `get_first_day_of_quarter` generates a float for `quarter` but `datetime.datetime()` doesn't except a float obj. Adding `int()` around `get_quarter(date)` could fix that, since you're for example now still in the 2nd quarter but you will recieve `quarter = 2.66667` – Philipp Zettl Jun 04 '18 at 11:55
6

Any how i found some simple solution in c# and converted it into python,

from datetime import datetime,timedelta
current_date=datetime.now()
currQuarter = (current_date.month - 1) / 3 + 1
dtFirstDay = datetime(current_date.year, 3 * currQuarter - 2, 1)
dtLastDay = datetime(current_date.year, 3 * currQuarter + 1, 1) + timedelta(days=-1)
Andy
  • 49,085
  • 60
  • 166
  • 233
Krishh
  • 680
  • 1
  • 6
  • 19
  • 8
    Getting `{ValueError}month must be in 1..12` when the current_date is in the last quarter. – Wasae Shoaib Nov 07 '18 at 12:04
  • The solution to fix this problem is to use the following code: `quarter = (month-1)//3+1` `initialDayQuarter = datetime(year, 3 * quarter - 2, 1)` `lastDayQuarter = datetime(year, (3 * quarter)%12+1, 1) + timedelta(days=-1)` – abautista Mar 28 '20 at 02:47
  • 2
    I only want to suggest to make currQuarter as integer. `currQuarter = int((current_date.month - 1) / 3 + 1)` And also to avoid the CamelCase :D – Save Sep 16 '22 at 09:06
2

Here's a one/two liner to get the start/end date of the current quarter.

from datetime import datetime
import math
from dateutil.relativedelta import relativedelta  # requires python-dateutil

start_of_quarter = datetime(year=datetime.now().year, month=((math.floor(((datetime.now().month - 1) / 3) + 1) - 1) * 3) + 1, day=1)

end_of_quarter = start_of_quarter + relativedelta(months=3, seconds=-1)
Luke Cousins
  • 2,068
  • 1
  • 20
  • 38
1

pendulum has a much more intuitive implementation.

import pendulum
dt = pendulum.datetime(2021, 3, 23)
print(dt.first_of('quarter'))
print(dt.last_of('quarter'))
2021-01-01T00:00:00+00:00
2021-03-31T00:00:00+00:00
mmann1123
  • 5,031
  • 7
  • 41
  • 49
0

Building off of the answer from Krishh, but addressing several issues found:

  1. calculating last day in Quarter 4
  2. Wasae Shoaib's comment about raising a ValueError
  3. TypeError with a float being passed instead of an integer

Using relativedeta instead and shifting the correctly calculated start date by three months, we end up with a much more reliable way to get at the quarter end date.

from datetime import datetime
from dateutil.relativedelta import relativedelta
current_date = datetime.now()
currQuarter = int((current_date.month - 1) / 3 + 1)
dtFirstDay = datetime(current_date.year, 3 * currQuarter - 2, 1)
dtLastDay = dtFirstDay + relativedelta(months=3, days=-1)
Kevin
  • 27
  • 5
0

I did of a lot of tests to find the solution that fit my need and I will be happy if it helps someone else :

            datval = fields.date.today()
            if datval.month < 4 :
               self.start_date = fields.date.today().replace(month=10, day=1)
               self.end_date = fields.date.today().replace(month=12, day=31)
            elif datval.month < 7 :
               self.start_date = fields.date.today().replace(month=1, day=1)
               self.end_date = fields.date.today().replace(month=3, day=31)
            elif datval.month < 10 :
               self.start_date = fields.date.today().replace(month=4, day=1)
               self.end_date = fields.date.today().replace(month=6, day=30)
            else : 
               self.start_date = fields.date.today().replace(month=7, day=1)
               self.end_date = fields.date.today().replace(month=9, day=30)
0

Get start and end points for: week, month, quarter and year https://gist.github.com/dejurin/236b398dc4b8064685702a27a3df612b

from datetime import date
from dateutil.relativedelta import relativedelta

def start_end_day(sunmon: bool = True):
    today = date.today()
    curr_quarter = int((today.month - 1) / 3 + 1)
    
    dayofweek = [today.weekday(),today.isoweekday()][sunmon]
    
    week_start = today - relativedelta(days=dayofweek)
    week_end = week_start + relativedelta(days=6)
    
    month_start = date(today.year,today.month, 1)
    month_end = month_start + relativedelta(months=1, days=-1)
    
    quarter_start = date(today.year, 3 * curr_quarter - 2, 1)
    quarter_end = quarter_start + relativedelta(months=3, days=-1)
    
    year_start = date(today.year, 1, 1)
    year_end = year_start + relativedelta(years=1, days=-1)
    
    return ((week_start,week_end),(month_start,month_end),(quarter_start,quarter_end),(year_start,year_end))

"""
Current date: 18/02/2022
"""
"""
((datetime.date(2022, 2, 13), datetime.date(2022, 2, 19)),
 (datetime.date(2022, 2, 1), datetime.date(2022, 2, 28)),
 (datetime.datetime(2022, 1, 1, 0, 0), datetime.datetime(2022, 3, 31, 0, 0))
  (datetime.date(2022, 1, 1), datetime.date(2022, 12, 31)))
"""
falselight
  • 527
  • 7
  • 11