# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

`parse_datetime` is a Rust crate (part of the [uutils](https://github.com/uutils) project) that parses human-readable date/time strings into jiff `Zoned` objects. It aims for GNU `date` compatibility. Formerly called `humantime_to_duration`.

## Build & Test Commands

Use `-q` on `cargo` to suppress compilation output and keep logs cheap.

```bash
cargo build -q                       # Build
cargo test -q                        # Run all tests
cargo test -q <test_name>            # Run a single test
cargo test -q --lib                  # Run unit tests only (in src/)
cargo test -q --test time            # Run a specific integration test file
```

### Fuzzer

```bash
cd fuzz && cargo +nightly fuzz run -q fuzz_parse_datetime -- -verbosity=0
```

## Architecture

The crate exposes two public functions (`parse_datetime` and `parse_datetime_at_date` in `src/lib.rs`) that delegate to the internal parsing engine in `src/items/`.

### Parsing Pipeline

1. **`src/items/mod.rs`** — Top-level parser. Uses [winnow](https://docs.rs/winnow) combinators to parse input into a sequence of `Item` variants (Date, Time, Relative, Weekday, Offset, Timestamp, etc.). The grammar is documented in the `parse()` function's doc comment.

2. **`src/items/*.rs`** — Each module parses one item type matching the GNU date spec:
   - `combined` — combined date+time (e.g. ISO 8601)
   - `date` — calendar dates (ISO, US, literal month formats)
   - `time` — time of day (24h, 12h/meridiem)
   - `relative` — relative durations ("3 days", "yesterday", "ago")
   - `weekday` — day-of-week items with optional ordinals ("next thursday")
   - `offset` — named timezone offsets ("UTC+07:00")
   - `timezone` — TZ rule parsing (`TZ="Europe/Paris"`)
   - `epoch` — unix timestamps ("@1234567890")
   - `pure` — bare digit strings (interpreted as year or HHMM)
   - `year` — standalone year parsing
   - `primitive` — shared low-level parsers (digits, whitespace)
   - `ordinal` — text/numeric ordinals ("first", "next", "+3")

3. **`src/items/builder.rs`** — `DateTimeBuilder` collects parsed items and resolves them against a base date/time to produce a final `Zoned`. The `TryFrom<Vec<Item>>` impl enforces constraints (e.g. no duplicate dates/times).

### Testing

- **Unit tests** live alongside source in `src/lib.rs` and `src/items/mod.rs`
- **Integration tests** in `tests/time.rs` and `tests/date.rs` use `rstest` for parameterized tests; expected values come from GNU `date` output
- Test helper in `tests/common/mod.rs`

### Key Dependencies

- **jiff** — timezone-aware datetime library (replaces chrono)
- **winnow** — parser combinator framework (fork/successor of nom)
- **rstest** — parameterized test framework (dev only)

## Shared conventions

@../coreutils-claude/common/coding-style.md
@../coreutils-claude/common/ci.md
@../coreutils-claude/common/testing.md
@../coreutils-claude/common/code.md
@../coreutils-claude/common/commit.md
