Amistad
Amistad

Reputation: 7410

finding the year and quarter from a datetime object in python

I have a requirement to find the completed quarter(1 to 4 from Jan to Dec), given a certain date. Note that it is not the current quarter but the completed quarter. By that I mean that if 1st Jan is the input date, then the completed quarter is 4 and not 1. The small code snippet that I have is as follows:

>>> import datetime
>>> import math
>>> now = datetime.datetime(2015, 1, 1, 0, 0, 0, 0)
>>> present_quarter = int(math.ceil(now.month/3.))
>>> completed_quarter = (present_quarter - 1) if present_quarter != 1 else 4
>>> completed_quarter
4

However what I need is the year as well so that the output is :

2014-4

What is the best way to do this ? Can the output remain a datetime object and not a string by which I mean does Python support a datetime object like Year-Quarter

Upvotes: 4

Views: 18070

Answers (3)

Prawit Chaivong
Prawit Chaivong

Reputation: 11

How about extend datetime

class Quarter(datetime):
    def __init__(self, *args, **kwargs):
        super(Quarter, self).__init__(*args, **kwargs)
        present_quarter = int(math.ceil(self.month/3))
        self.quarter = (present_quarter-1) if present_quarter != 1 else 4

Using it.

q = Quarter(2015,1,1,0,0,0)
# Or
q = Quarter.now()
# Getting quarter
print q.quarter

Upvotes: 1

Padraic Cunningham
Padraic Cunningham

Reputation: 180481

You just need to catch the first quarter:

def qrt(now):
    first_qrt = now.month < 4
    return now.year - first_qrt, (now.month - 1) // 3 if not first_qrt else 4

Upvotes: 2

Martijn Pieters
Martijn Pieters

Reputation: 1123420

You could simply map the month to the quarter and a year delta (you need last year for Q4):

def completed_quarter(dt):
    prev_quarter_map = ((4, -1), (1, 0), (2, 0), (3, 0))
    quarter, yd = prev_quarter_map[(dt.month - 1) // 3]
    return (dt.year + yd, quarter)

This translates the month to a value between 0 and 3, then translates that into a quarter number and a year delta. Adding the year delta to the current year gives you the correct year for that completed previous quarter.

Demo:

>>> def completed_quarter(dt):
...     prev_quarter_map = ((4, -1), (1, 0), (2, 0), (3, 0))
...     quarter, yd = prev_quarter_map[(dt.month - 1) // 3]
...     return (dt.year + yd, quarter)
... 
>>> from datetime import date
>>> completed_quarter(date(2015, 1, 12))
(2014, 4)
>>> completed_quarter(date(2015, 8, 31))
(2015, 2)
>>> completed_quarter(date(2015, 12, 31))
(2015, 3)

The datetime module has no objects that can model a quarter; you can have a date (which has to have valid year, month and day values) or a date and time (adding on a valid hour, minute, second and microsecond value, with optional timezone).

Upvotes: 5

Related Questions