Mastering Datetime Arithmetic with bttf: A Modern CLI Swiss Army Knife
Handling dates and times in a terminal is a notoriously frustrating experience. For many developers, the standard date command is a tool used infrequently enough that its idiosyncratic flags and behaviors are easily forgotten, necessitating a constant return to the manual.
Enter bttf, a command-line tool designed for datetime arithmetic, parsing, and formatting. Created by BurntSushi, bttf is not intended as a drop-in replacement for POSIX date, but rather as a modern alternative that prioritizes ergonomics and power. Built on top of the Jiff library, it brings sophisticated datetime logic to the shell, allowing users to perform complex calculations and transformations with succinct syntax.
Beyond Simple Formatting
While basic time printing is a given, bttf excels in relative time calculations and sequence generation. Instead of writing complex bash wrappers to find a specific date, bttf allows for natural language-like queries and precise arithmetic.
Relative Time and Arithmetic
Adding or subtracting durations is straightforward. Whether you need to find a date from a week ago or calculate a date six months into the future, the syntax is intuitive:
$ bttf time add -1w now
$ bttf time add '1 week, 12 hours ago' now
$ bttf time add 6mo now
Complex Sequence Generation
One of the most powerful features of bttf is its ability to generate sequences of dates based on specific constraints. This is particularly useful for scheduling or reporting tasks. For example, generating the second Tuesday of every month until the end of the year can be done in a single line:
$ bttf time seq monthly -w 2-tue --until $(bttf time end-of year now) | bttf time fmt -f '%a, %F'
As one community member noted, this capability can replace dozens of lines of custom bash scripting for tasks like newsletter scheduling or holiday-adjusted calendars.
The Power of "Tagging" and Pipeline Integration
Most datetime tools only process datetime strings. bttf introduces a unique tag command that allows it to operate on arbitrary data. By wrapping datetimes found in logs or command output into a JSON lines format, bttf can perform operations on the time data while preserving the surrounding context.
This enables advanced workflows, such as reformatting timestamps in a log file in place:
$ bttf tag lines /tmp/access.log | bttf time in system | bttf time fmt -f '%c' | bttf untag -s
Real-world Example: Git Repository Analysis
The author demonstrates the versatility of the tag exec command by combining it with git log. This allows a user to list all files in a repository, sorted by their most recent commit date, formatted in local time:
$ git ls-files | bttf tag exec git log -n1 --format='%aI' | bttf time in system | bttf time sort | bttf time fmt -f '%a %Y-%m-%d %H:%M:%S' | bttf untag -f '{tag}|t{data}'
Technical Foundations: Civil Time vs. Absolute Instants
A critical technical distinction made by bttf (via the Jiff library) is the separation of "civil time" and "absolute instants."
Many standard libraries and the GNU date command often conflate these two, leading to subtle bugs during Daylight Saving Time (DST) transitions. As highlighted in the HN discussion:
"You cannot answer 'what's 30 days from 2024-03-08 in America/New_York' without picking a side — DST means that's either 29d23h or 30d0h of elapsed time, and most APIs silently pick one without telling you."
By treating these as different types, bttf ensures that arithmetic is predictable and mathematically sound, following the philosophy of the Temporal proposal in TC39 (JavaScript).
Installation and Performance
bttf is written in Rust and is available via crates.io. It offers flexible installation options, including precompiled binaries for Windows, macOS, and Linux.
For those concerned with binary size or compile times, locale support can be disabled during installation:
cargo install bttf --no-default-features
Conclusion
While some argue that LLMs have obsoleted the need for specialized datetime DSLs, the precision, reproducibility, and pipeline-ability of a tool like bttf make it indispensable for automation and systems administration. By bridging the gap between raw timestamps and human-readable local time, bttf transforms the terminal from a place of manual date calculations into a powerful engine for temporal data processing.