tu; when; dateutils
Since we talked about time, yesterday, let’s build on that “theme” with a couple Rust-based utilities, and a bundle in C, that make dealing with time at the CLI (dare I say) a joy.
TL;DR
(This is an AI-generated summary of today’s Drop.)
Hey, so Perplexity failed miserably four times, even after changing the model mid-way, so no TL;DR, today.
tu

tu knows that we humans rarely say things like “2024-05-06T08:14:00 EST5EDT” out loud to refer to times an dates (I mean, we should, but we don’t). We say things like “20 minutes from now”, or “next Thursday” (though “next” has issues of its own).
Running tu shows examples, and they’re _live”, meaning it runs code at that moment to generate the output. Here’s the output just before I scheduled this post:
tu today -> 2024-05-06T12:21:39.019429Z
tu tomorrow -> 2024-05-07T12:21:39.019429Z
tu 2 day -> 2024-05-08T12:21:39.019429Z
tu 9 week -> 2024-07-08T12:21:39.019429Z
tu 1 month -> 2024-06-06T00:00:00Z
tu Wed, 14 Feb 2024 23:16:09 GMT -> 2024-02-14T23:16:09Z
tu 2024-04-10T13:31:46+04:00 -> 2024-04-10T09:31:46Z
Sure, you can use the Linux date command to do some fancy human maths like:
$ date -d '+1 hour' '+%F %T'
2024-05-06 09:23:29
But, you have to use a format specifier and remember that the macOS date command is different than linux (or, brew install coreutils and remember to use gdate).
With tu, you are guaranteed to get the output in the same UTC timestamp format every time.
IMO it’s worth the ~640K of SSD space to carve out on all your installs.
when

So, tu helps us with maths and durations, and when helps us with the increasingly complex “when is it X in Y time zone?”. It uses clap without some of the niceities enabled, so you’re (sadly) in double-quote Hades if you do use it:
$ when "now in london"
time: 13:28:30 (afternoon)
date: 2024-05-06 (Monday)
zone: Europe/London (BST; +0100)
location: London (ENG; United Kingdom)
time: 08:28:30 (morning)
date: 2024-05-06 (Monday)
zone: America/New_York (EDT; -0400)
You can also get the output in JSON, something every modern tool should emulate:
$ when 'now in yyz -> sfo -> vie -> lhr' --json
[
{
"datetime": "2024-05-06T08:30:04.634074-04:00",
"time_of_day": "morning",
"timezone": {
"name": "America/Toronto",
"abbrev": "EDT",
"utc_offset": "-0400"
},
"location": {
"name": "Toronto Pearson International Airport",
"country": "Canada"
}
},
{
"datetime": "2024-05-06T05:30:04.634074-07:00",
"time_of_day": "early_morning",
"timezone": {
"name": "America/Los_Angeles",
"abbrev": "PDT",
"utc_offset": "-0700"
},
"location": {
"name": "San Francisco International Airport",
"admin_code": "CA",
"country": "United States"
}
},
{
"datetime": "2024-05-06T14:30:04.634074+02:00",
"time_of_day": "afternoon",
"timezone": {
"name": "Europe/Vienna",
"abbrev": "CEST",
"utc_offset": "+0200"
},
"location": {
"name": "Vienna International Airport",
"country": "Austria"
}
},
{
"datetime": "2024-05-06T13:30:04.634074+01:00",
"time_of_day": "afternoon",
"timezone": {
"name": "Europe/London",
"abbrev": "BST",
"utc_offset": "+0100"
},
"location": {
"name": "London Heathrow Airport",
"admin_code": "ENG",
"country": "United Kingdom"
}
}
]
This one eats up ~5.5M, so you may only want to have this around if you need to frequently grok bits in other timezones. If not, then, perhaps, use the online version. It uses a WASM-ified version of the code.
dateutils

dateutils are a “a bunch of tools that revolve around fiddling with dates and times on the command line with a strong focus on use cases that arise when dealing with large amounts of financial data.” There’s a whopping ten of them:
strptimeCommand line version of the C functiondateaddAdd durations to dates or timesdateconvConvert dates or times between calendarsdatediffCompute durations between dates or timesdategrepGrep dates or times in input streamsdateroundRound dates or times to “fuller” valuesdateseqGenerate sequences of dates or timesdatesortSort chronologically.datetestCompare dates or timesdatezoneConvert date/times to timezones in bulk
I find dateseq to be especially handy if R is not around for me, so let’s show that off along with dategrep:
$ dateseq 2024-05-06 2024-05-31 --skip sat,sun | dategrep '>2024-05-14'
2024-05-15
2024-05-16
2024-05-17
2024-05-20
2024-05-21
2024-05-22
2024-05-23
2024-05-24
2024-05-27
2024-05-28
2024-05-29
2024-05-30
2024-05-31
I also use strptime a fair amount, and datesort comes in handy if you deal with monsters who decide YYYY-MM-DD (The One True Date Format™) is too banal for them.
FIN
Remember, you can follow and interact with the full text of The Daily Drop’s free posts on Mastodon via @dailydrop.hrbrmstr.dev@dailydrop.hrbrmstr.dev ☮️
Leave a comment