Skip to content

feat: support time-of-day in due dates - #60

Merged
alexanderdavidsen merged 1 commit into
masterfrom
feat/due-date-time
Jun 24, 2026
Merged

alexanderdavidsen merged 1 commit into
masterfrom
feat/due-date-time

Conversation

@alexanderdavidsen

Copy link
Copy Markdown
Collaborator

Closes #58.

What

Adds time-of-day support to due dates, which were previously whole-day deadlines only.

New accepted formats (in addition to YYYY-MM-DD, today, tomorrow):

  • ISO date-time — YYYY-MM-DDTHH:MM[:SS] and YYYY-MM-DD HH:MM[:SS]
  • Relative offsets — today+HHMM, tomorrow+HHMM (that day at HH:MM), and now+HHMM (HH hours / MM minutes from now). The colon is optional (14:30 == 1430).
  • now keyword

Behaviour

  • Due dates with a time render as YYYY-MM-DD HH:MM and are classified time-granularly — they flip to Overdue once the instant passes.
  • Whole-day deadlines (local midnight) keep date-granular behaviour, so due:today stays due today all day (no regression).

Entry-path nuance

A due: token is whitespace-split, so it can't contain a space — the token form uses the T separator (due:2026-07-01T14:30). The --due flag accepts the quoted space form too (--due @3 "2026-07-01 14:30").

Touched

  • taskbook-common/src/due.rs — parsing, formatting, status (core change)
  • CLI / TUI / MCP help text + schema descriptions
  • CLAUDE.md docs

Test plan

  • cargo test --workspace — green (new unit tests cover ISO date-time, space separator, seconds, midnight-renders-as-date, today+/tomorrow+/now+ offsets, invalid offsets, and time-granular vs whole-day status)
  • cargo clippy --workspace --all-targets — clean
  • cargo fmt --all --check — clean

🤖 Generated with Claude Code

Extend due-date parsing beyond whole-day deadlines:

- ISO date-time: `YYYY-MM-DDTHH:MM[:SS]` and `YYYY-MM-DD HH:MM[:SS]`
- Relative offsets: `today+HHMM`, `tomorrow+HHMM` (that day at HH:MM)
  and `now+HHMM` (HH hours, MM minutes from now); colon optional
- A bare `now` keyword

Due dates with a time render as `YYYY-MM-DD HH:MM` and are classified
time-granularly (Overdue once the instant passes). Whole-day deadlines
(local midnight) keep their date-granular behaviour, so `due:today`
stays "due today" all day.

Note: a `due:` token cannot contain a space, so the token form uses the
`T` separator (`due:2026-07-01T14:30`); the `--due` flag accepts the
quoted space form too.

Updates CLI/TUI/MCP help text and docs.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Copilot AI review requested due to automatic review settings June 24, 2026 11:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds time-of-day support to due dates in taskbook-common, expanding parsing/formatting and switching status classification to be time-granular when a due time is present, while keeping whole-day (midnight) dues date-granular.

Changes:

  • Extend due parsing to accept ISO date-times, now, and relative +HHMM offsets; update formatting to include HH:MM when a time is present.
  • Update due-status logic to flip timed dues to Overdue once the instant passes (while preserving all-day behavior for midnight dues).
  • Refresh CLI/TUI/MCP/docs help text and add unit tests for the new formats.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
crates/taskbook-common/src/due.rs Core parsing/formatting/status logic updated for time-of-day dues + added unit tests
crates/taskbook-common/src/board.rs Update CLI token help text and add a parsing test for due:...T...
crates/taskbook-client/src/tui/command_parser.rs Update /task usage hint to reflect time-capable due tokens
crates/taskbook-client/src/mcp/tools.rs Update MCP JSON schema descriptions for new due-date formats
crates/taskbook-client/src/main.rs Add CLI help examples demonstrating due date-times and relative offsets
CLAUDE.md Update docs/examples for the expanded due-date syntax

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +71 to +77
let dt = match offset {
None => base_dt,
Some(off) => {
let (hours, minutes) = parse_hhmm(off)?;
base_dt + Duration::hours(hours) + Duration::minutes(minutes)
}
};
Comment on lines 128 to 132
if args.is_empty() {
return Err(ParseError {
message: "Usage: /task [@board] description [p:1-3] [due:YYYY-MM-DD]".to_string(),
message: "Usage: /task [@board] description [p:1-3] [due:YYYY-MM-DD[THH:MM]]"
.to_string(),
});
Comment on lines 37 to 41
"boards": { "type": "array", "items": { "type": "string" }, "description": "Boards to place the task on (defaults to My Board)" },
"priority": { "type": "integer", "minimum": 1, "maximum": 3, "description": "1 = normal, 2 = medium, 3 = high (default 1)" },
"tags": { "type": "array", "items": { "type": "string" }, "description": "Tags for the task" },
"due_date": { "type": "string", "description": "Due date: YYYY-MM-DD, today, or tomorrow" }
"due_date": { "type": "string", "description": "Due date: YYYY-MM-DD, 'YYYY-MM-DD HH:MM', today, tomorrow, now, or today+HHMM / tomorrow+HHMM / now+HHMM" }
},
Comment on lines 76 to 80
"id": { "type": "integer", "description": "Item id" },
"description": { "type": "string", "description": "New description" },
"priority": { "type": "integer", "minimum": 1, "maximum": 3, "description": "New priority (tasks only)" },
"due_date": { "type": "string", "description": "New due date (YYYY-MM-DD, today, tomorrow) or 'none' to clear (tasks only)" },
"due_date": { "type": "string", "description": "New due date (YYYY-MM-DD, 'YYYY-MM-DD HH:MM', today, tomorrow, now, today+HHMM / tomorrow+HHMM / now+HHMM) or 'none' to clear (tasks only)" },
"boards": { "type": "array", "items": { "type": "string" }, "description": "Replace the item's boards" },
Comment thread CLAUDE.md
tb --move @<id> board # Move to board
tb --priority @<id> <1-3> # Set priority
tb --due @<id> <date> # Set due date (YYYY-MM-DD, today, tomorrow) or none to clear
tb --due @<id> <date> # Set due date (YYYY-MM-DD[ HH:MM], today, tomorrow, now, *+HHMM) or none to clear
@alexanderdavidsen
alexanderdavidsen merged commit c9510a9 into master Jun 24, 2026
4 checks passed
@alexanderdavidsen
alexanderdavidsen deleted the feat/due-date-time branch June 24, 2026 11:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

due date to allow sio date with time

2 participants