Skip to content

Instantly share code, notes, and snippets.

@oliverlambson
Last active September 15, 2024 23:32
Show Gist options
  • Save oliverlambson/985080f3829930ce46e482c9f0e6297a to your computer and use it in GitHub Desktop.
Save oliverlambson/985080f3829930ce46e482c9f0e6297a to your computer and use it in GitHub Desktop.
A `click.Date` type

A click.Date type

What's the problem?

click doesn't have a builtin date type, only a datetime. (They won't be adding one either.)

This litters my cli code with an annoying convert to date chore that I end up using all over the place:

@click.command()
@click.argument("datetime_", type=click.DateTime())
def old_main(datetime_: datetime.datetime) -> None:
    date = datetime_.date()  # annoying, I want to pass in a date
    click.echo(f"Date: {date}")

How to make your own click date type

import datetime
from typing import Any, Optional

import click


class ClickDate(click.ParamType):
    name = "date"

    def convert(
        self, value: Any, param: Optional[click.Parameter], ctx: Optional[click.Context]
    ) -> datetime.date:
        if isinstance(value, datetime.date):
            return value

        try:
            return datetime.date.fromisoformat(value)
            # if you want, you could extend to accept other formats, 
            # but `YYYY-MM-DD` is the only one I care about
        except ValueError:
            self.fail(f"{value!r} is not a valid date", param, ctx)

You can then use dates easily:

@click.command()
@click.argument("date", type=ClickDate())
def main(date: datetime.date) -> None:
    click.echo(f"Date: {date}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment