Interactive terminal date and time picker for Typer CLIs
Project description
its-a-dt
Interactive terminal date and time picker for Python CLIs. Built on prompt_toolkit, with a composable Bounds API for constraining what users can select.
Navigate with arrow keys, type values directly, or combine both. Multi-step flows (date, datetime) support back navigation with backspace.
Install
pip install its-a-dt
CLI
Run the full datetime wizard (no subcommand), or pick one field at a time:
its-a-dt # year → month → day → time
its-a-dt datetime --min 2025-01-01 --max 2025-12-31
its-a-dt date --days-of-week mon,wed,fri
its-a-dt year
its-a-dt month --year 2025
its-a-dt day --year 2025 --month 6 --days-of-week mon,wed,fri
its-a-dt time --interval 15min --hours 9-17
Common options:
| Option | Description |
|---|---|
--min, --max |
Earliest/latest allowed value (ISO date or datetime) |
--days-of-week |
Comma-separated weekdays (mon,wed,fri) |
--days-of-month |
Comma-separated days of month (1,15) |
--hours |
Allowed hours (9-17 or 9,10,11,15) |
--interval |
Time step (15min, 30min, 1hr, 2hr, …) |
--default, -d |
Starting value |
--eager |
Auto-advance as soon as a value is fully specified |
Press q or Ctrl-C to cancel. Selected values are printed to stdout.
Python API
Import individual pickers or use the composed flows:
from datetime import datetime
from its_a_dt import Bounds, pick_date, pick_datetime, pick_day, pick_month, pick_time, pick_year
from its_a_dt import Cancelled, GoBack
bounds = Bounds(max=datetime(2025, 12, 31))
year = pick_year(bounds=bounds)
month = pick_month(year=year, bounds=bounds)
day = pick_day(year=year, month=month, bounds=Bounds.days_of_week_only("mon", "fri"))
t = pick_time(bounds=Bounds.minute_interval(15))
# or run the full flow in one call
dt = pick_datetime(bounds=bounds)
Each picker returns the selected value, or GoBack if the user navigated to the previous step. Raise Cancelled when the user quits (press q).
Bounds
Bounds limits which values appear in each picker. Combine constraints as needed:
Bounds(max=datetime(2025, 12, 31))
Bounds.days_of_week_only("mon", "wed", "fri")
Bounds.days_of_month_only(1, 15)
Bounds.hours_only(9, 10, 11)
Bounds.hour_range(9, 17)
Bounds.minute_interval(15) # 0, 15, 30, 45
Bounds.hour_interval(2) # every 2 hours; minutes locked to :00
Date-range bounds affect year, month, and day pickers. Hour and minute constraints apply to the time picker. When picking a time for a specific date, pass on_date so min/max datetime bounds are evaluated correctly.
Eager mode
By default, typed values are committed on Enter (or → in the time picker). With eager=True, pickers auto-advance as soon as the input uniquely identifies a value:
- Year — four digits entered
- Month — enough letters to identify one month (
f→ February,jul→ July) - Day — one or two digits when unambiguous
- Time — hour/minute digits when fully specified
Invalid input in eager mode clears the field; in standard mode it is kept so you can keep editing.
Development
See development.md for local setup, testing, and publishing.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file its_a_dt-0.1.1.tar.gz.
File metadata
- Download URL: its_a_dt-0.1.1.tar.gz
- Upload date:
- Size: 16.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a3fb5a933c447ac927d4b7a30c4800c98a3fd10e0f9f82d9daf4a396b95b94d5
|
|
| MD5 |
dcf71a60257d25d9072d7b6dfe029311
|
|
| BLAKE2b-256 |
30c6c0b0ee1716e6b7c770ef57ff0893b6d9c951c78d3534735daadc2a409cfb
|
Provenance
The following attestation bundles were made for its_a_dt-0.1.1.tar.gz:
Publisher:
publish.yml on alanjschoen/its-a-dt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
its_a_dt-0.1.1.tar.gz -
Subject digest:
a3fb5a933c447ac927d4b7a30c4800c98a3fd10e0f9f82d9daf4a396b95b94d5 - Sigstore transparency entry: 1824963127
- Sigstore integration time:
-
Permalink:
alanjschoen/its-a-dt@6c7f1f484ba124fa1936ac2c76b1945a2f9ce126 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/alanjschoen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6c7f1f484ba124fa1936ac2c76b1945a2f9ce126 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file its_a_dt-0.1.1-py3-none-any.whl.
File metadata
- Download URL: its_a_dt-0.1.1-py3-none-any.whl
- Upload date:
- Size: 20.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
12f49d8798b665bfd8247d0a54f9c18bab2c721d9866484a0cb5c0a4065485d6
|
|
| MD5 |
3a66a35c3efb5ea63303d1294121fcee
|
|
| BLAKE2b-256 |
be94c543d5255c7e4a6aa3e31fe6b22a6951c3d941814a273fd3e35ff6f65abc
|
Provenance
The following attestation bundles were made for its_a_dt-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on alanjschoen/its-a-dt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
its_a_dt-0.1.1-py3-none-any.whl -
Subject digest:
12f49d8798b665bfd8247d0a54f9c18bab2c721d9866484a0cb5c0a4065485d6 - Sigstore transparency entry: 1824963302
- Sigstore integration time:
-
Permalink:
alanjschoen/its-a-dt@6c7f1f484ba124fa1936ac2c76b1945a2f9ce126 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/alanjschoen
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@6c7f1f484ba124fa1936ac2c76b1945a2f9ce126 -
Trigger Event:
workflow_dispatch
-
Statement type: