Handling "Fuzzy" date with missing values

How do I deal with an API that returns Fuzzy date with missing values? My initial plan was to check year, month, and day and then pass them into datetime.date but I just learnt that date requires all 3.

# API response
      "startDate": {
        "year": 2023,
        "month": 9,
        "day": 29
      },
      "endDate": {
        "year": 2024,
        "month": 3,
        "day": null
      },

Any of these can be None or all of these can be None.

In my head I planned to achieve something like this:

# Doesn't actually work, because date requires all 3
def _fuzzy_date_handler(year, month, day):

    if year and month and day:
        return date(year=year, month=month, day=day)

    elif year and month:
        return date(year=year, month=month)
    
    elif year:
        return date(year=year)
    
    else:
        return None # all 3 are null

Easiest solution I can think of is to use a very simple dataclass instead of a proper date library:

@dataclass
class FuzzyDate:
    year: int | None
    month: int | None
    day: int | None

Is there a library that handles such cases already? If not, how should I go about dealing with this?

I guess the first question is: What can you DO with this date? If all you need to do is retain the year, month, and day, without doing any calculations or comparisons or anything, the dataclass is probably the right choice.

Only thing I wanted to do was something like date.isoformat_ish() and get a string like 2024-02-01 if all 3 are available, 2024-02 for only 2, 2024 if year’s the only thing I got and probably just return an empty string if none

This isn’t a usecase for datetime.date. It is supposed to represent a specific day, which isn’t what you have. Use a custom dataclass with custom formatting options.

That’s still very doable with a dataclass - you can have a method that returns that. (You could even name it to match what datetime.date has, if that’s convenient.)

1 Like

Thank you! I’ll stick with dataclass then

1 Like