2026-05-15
You've done it. I've done it. Everyone has done it: piped date output through awk through sed trying to figure out which Tuesday is two weeks before the last business day of the quarter. dateutils (Hroptatyr's dateutils, not the Python package) is a family of seven small programs that treat dates and times as first-class data. It's been around since 2011, ships in every distro, and almost no one knows it exists.
The tools: dconv (convert formats), dadd (add durations), ddiff (subtract dates), dseq (generate ranges), dround (snap to boundaries), dgrep (filter by date), and dsort (sort lines by embedded dates).
The "what's the date 47 business days from now" problem:
$ dadd today +47bd
2026-07-20
$ dadd 2026-05-15 +47bd --skip sat,sun,2026-07-04
2026-07-21
Try writing that with GNU date. I'll wait. The --skip flag accepts weekdays AND specific holiday dates. bd means "business day" and the tool understands it natively.
Generate every Tuesday and Thursday between two dates:
$ dseq 2026-05-15 2026-06-15 --skip sun,mon,wed,fri,sat
2026-05-19
2026-05-21
2026-05-26
2026-05-28
...
Compute the time between events with arbitrary unit output:
$ ddiff 2026-05-15T09:00:00 2026-05-15T17:43:21 -f '%H hours, %M minutes, %S seconds'
8 hours, 43 minutes, 21 seconds
$ ddiff 2025-01-01 2026-05-15 -f '%mmo %dd'
16mo 14d
$ ddiff 1970-01-01 today -f '%w weeks'
2940 weeks
The killer app is dgrep, which filters log lines by parsing dates inside them — no regex required:
$ dgrep '>=2026-05-14T22:00:00' /var/log/syslog
$ dgrep --between 2026-05-15 2026-05-15 access.log | wc -l
And dsort sorts log lines by embedded timestamps, even when files have mixed formats — great for merging logs from different services:
$ cat nginx.log app.log | dsort -i '%Y-%m-%dT%H:%M:%S' > merged.log
dround snaps to boundaries — incredibly useful for bucketing time-series data:
$ dround 2026-05-15T14:37:22 /15m
2026-05-15T14:45:00
$ dround today /Mon # next Monday
2026-05-18
$ dround 2026-05-15 -1mo # one month earlier
2026-04-15
Everything composes. Want every other Friday for the next year, formatted as ISO weeks?
$ dseq today +1y --skip sun,mon,tue,wed,thu,sat \
| awk 'NR%2==1' \
| dconv -i '%Y-%m-%d' -f '%Y-W%V-%u'
2026-W20-5
2026-W22-5
2026-W24-5
...
The mainstream alternative is GNU date -d, which handles natural language ("next Friday", "2 weeks ago") but falls apart for business-day arithmetic, requires shell loops for sequences, can't grep logs, can't round, and produces a single date at a time. Python dateutil works but you've now written a script for what should be a pipeline.
Install with apt install dateutils, brew install dateutils, or pacman -S dateutils. On some distros the binaries are prefixed: dateutils.dadd instead of dadd.
