Date object with year and month only

Question:

Is it possible to create date object with year and month only? I don’t need day.

In [5]: from datetime import date

In [6]: date(year=2013, month=1)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-a84d4034b10c> in <module>()
----> 1 date(year=2013, month=1)

TypeError: Required argument 'day' (pos 3) not found

I’m using the date object as key in my dictionary and January 20 must have the same key as January 21, because they are in same month and year.

I used a simple integer before that as a month number. Unfortunately I need to know the year too!

Asked By: daGrevis

||

Answers:

No, you can’t do that. For your usecase, use a tuple instead:

key = (2013, 1)

Since you don’t need to do date manipulations on the value a tuple more than suffices.

Answered By: Martijn Pieters

As an addition to other answer, you can use namedtuple.

from collections import namedtuple
MyDate = namedtuple('MyDate', ['month', 'year'])
dkey = MyDate(year=2013, month=1)
Answered By: reader_1000

If you want to use datetime, you must follow its attributes. Here I quote it from the official website:

“An idealized naive date, assuming the current Gregorian calendar
always was, and always will be, in effect. Attributes: year, month,
and day.”

So, you can’t ignore day and remember to give assignment.

Answered By: Haimei
import datetime

date = datetime.date(year=2013, month=1, day=4)
str(date.year) + '-' + str(date.month)
Answered By: zeroclyy

This implements a class which is just like datetime.date, but you need not specify the day. i.e. It allows you to "create date object with year and month only."

class Mdate(datetime.date):
    """ A datetime.date where day doesn't matter. """

    def __new__(cls, year, month):
        """Python calls __new__ instead of __init__ for immutable objects."""
        return super().__new__(cls, year, month, 1)

    def __repr__(self):
        """Because you're implementing __new__ you also need __repr__ or else you get
        TypeError: __new__() takes 3 positional arguments but 4 were given."""
        return '{0}({1}, {2}, 1)'.format(self.__class__.__name__, self.year, self.month)

    def __reduce__(self):
        """You need __reduce__ to support pickling."""
        return (self.__class__, (self.year, self.month))

I have a boatload of code where the day of month is irrelevant, and removing the day from the date constructor clarifies that code.

Sample use:

d = Mdate(2020, 12)
Answered By: Kevin Kleinfelter
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.