Get date object for the first/last day of the current year

I need to get date objects for the first and last day in the current year.

Currently I'm using this code which works fine, but I'm curious if there's a nicer way to do it; e.g. without having to specify the month/day manually.

from datetime import date
a = date(date.today().year, 1, 1)
b = date(date.today().year, 12, 31)

The only real improvement that comes to mind is to give your variables more descriptive names than a and b.


from datetime import datetime

starting_day_of_current_year = datetime.now().date().replace(month=1, day=1)    
ending_day_of_current_year = datetime.now().date().replace(month=12, day=31)

There is nothing in the python library but there are external libraries that wrap this functionality up. For example, pandas has a timeseries library, with which you can do:

from datetime import date
from pandas.tseries import offsets

a = date.today() - offsets.YearBegin()
b = date.today() + offsets.YearEnd()

Whilst pandas is overkill if all you want is year begin and year end functionality, it also has support for a lot of other high level concepts such as business days, holiday calendars, month/quarter/year offsets: http://pandas.pydata.org/pandas-docs/stable/timeseries.html#dateoffset-objects


You'll have some funky stuff going on if you happen to be running this late on New Year's Eve and the two calls to today() cross the year boundary. It's safer to do this:

from datetime import date

epoch_year = date.today().year
year_start = date(epoch_year, 1, 1)
year_end = date(epoch_year, 12, 31)

import datetime
year = 2016
first_day_of_year = datetime.date.min.replace(year = year)
last_day_of_year = datetime.date.max.replace(year = year)
print(first_day_of_year, last_day_of_year)

duh.

What if we want to get the exact time the year begins or ends? Same thing. Replace datetime.date with datetime.datetime, and there you go, you got the first last day of year in datetime.datetime format.

To make this even fancier, wrap the whole thing in a function:

import datetime

def year_range(year, datetime_o = datetime.date):
    return (
        datetime_o.min.replace(year = year),
        datetime_o.max.replace(year = year)        
    )

print(year_range(2016, datetime.date))
print(year_range(2016, datetime.datetime))

Output:

(datetime.date(2016, 1, 1), datetime.date(2016, 12, 31))
(datetime.datetime(2016, 1, 1, 0, 0), datetime.datetime(2016, 12, 31, 23, 59, 59, 999999))