DateTime¶
You can specify a CLI parameter as a Python datetime.
Your function will receive a standard Python datetime object, and again, your editor will give you completion, etc.
from datetime import datetime
import typer
app = typer.Typer()
@app.command()
def main(birth: datetime):
print(f"Interesting day to be born: {birth}")
print(f"Birth hour: {birth.hour}")
if __name__ == "__main__":
app()
Typer will accept any string from datetime formats supported by Pydantic,
including Unix timestamps as seconds or milliseconds since the Unix epoch,
and several 'standard' options such as
* %Y-%m-%d
* %Y-%m-%dT%H:%M:%S
* %Y-%m-%d %H:%M:%S
* ...
Check it:
$ uv run python main.py --help
Usage: main.py [OPTIONS] {birth}
Arguments:
birth [required]
Options:
--help Show this message and exit.
// Pass a datetime
$ uv run python main.py 1956-01-31T10:00:00
Interesting day to be born: 1956-01-31 10:00:00
Birth hour: 10
// An invalid date
$ uv run python main.py july-19-1989
Usage: main.py [OPTIONS] {birth}
Try 'main.py --help' for help.
Error: Invalid value for 'birth': Input should be a valid datetime or date, invalid character in year
Custom date format¶
You can also customize the formats received for the datetime with the formats parameter.
formats receives a list of strings with the date formats that would be passed to datetime.strptime().
For example, let's imagine that you want to accept an ISO formatted datetime, but for some strange reason, you also want to accept a format with:
- first the month
- then the day
- then the year
- separated with "
/"
...It's a crazy example, but let's say you also needed that strange format:
from datetime import datetime
from typing import Annotated
import typer
app = typer.Typer()
@app.command()
def main(
launch_date: Annotated[
datetime,
typer.Argument(formats=["%Y-%m-%d", "%m/%d/%Y"]),
],
):
print(f"Launch will be at: {launch_date}")
if __name__ == "__main__":
app()
🤓 Other versions and variants
Tip
Prefer to use the Annotated version if possible.
from datetime import datetime
import typer
app = typer.Typer()
@app.command()
def main(
launch_date: datetime = typer.Argument(..., formats=["%Y-%m-%d", "%m/%d/%Y"]),
):
print(f"Launch will be at: {launch_date}")
if __name__ == "__main__":
app()
Tip
Notice the last string in formats: "%m/%d/%Y".
Check it:
// ISO dates work (first pattern)
$ uv run python main.py 1969-10-29
Launch will be at: 1969-10-29 00:00:00
// The strange custom format also works (second pattern)
$ uv run python main.py 10/29/1969
Launch will be at: 1969-10-29 00:00:00
// But notice that a 'standard' date format now doesn't work anymore, as it's not included in 'formats':
$ uv run python main.py 1969-10-29T10:00:00
Usage: main.py [OPTIONS] {launch_date}
Try 'main.py --help' for help.
Error: Invalid value for 'launch_date': Value error, '1969-10-29T10:00:00' does not match the formats '%Y-%m-%d', '%m/%d/%Y'.