diff --git a/NEWS.md b/NEWS.md index 2a00fd24..1165c962 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # cli (development version) +* New `{.duration}` and `{.time_ago}` inline styles to format durations + and relative times (@jjjermiah, #814). + # cli 3.6.6 * New `{.num}` and `{.bytes}` inline styles to format numbers diff --git a/R/themes.R b/R/themes.R index 26c94d18..71ada3a0 100644 --- a/R/themes.R +++ b/R/themes.R @@ -267,6 +267,15 @@ builtin_theme <- function(dark = getOption("cli.theme_dark", "auto")) { ), span.num = list( transform = function(x) format_num$pretty_num(as.numeric(x)) + ), + span.duration = list( + transform = function(x) { + if (inherits(x, "difftime")) units(x) <- "secs" + format_time$pretty_sec(as.numeric(x)) + } + ), + span.time_ago = list( + transform = function(x) format_time_ago$time_ago(as.POSIXct(x, origin = "1970-01-01")) ) ) } diff --git a/tests/testthat/_snaps/inline-2.md b/tests/testthat/_snaps/inline-2.md index 4ffce625..7004ff24 100644 --- a/tests/testthat/_snaps/inline-2.md +++ b/tests/testthat/_snaps/inline-2.md @@ -458,3 +458,46 @@ Output [1] "--- 10 k, 20 k, 30 k, and 40 k ---" +# .duration + + Code + format_inline("--- {.duration 0.042} ---") + Output + [1] "--- 42ms ---" + Code + format_inline("--- {.duration 90} ---") + Output + [1] "--- 1m 30s ---" + Code + format_inline("--- {.duration 3661} ---") + Output + [1] "--- 1h 1m 1s ---" + Code + dt_mins <- as.difftime(1.5, units = "mins") + format_inline("{.duration {dt_mins}}") + Output + [1] "1m 30s" + Code + dt_days <- as.difftime(30, units = "days") + format_inline("{.duration {dt_days}}") + Output + [1] "30d" + +# .time_ago + + Code + t <- as.numeric(Sys.time() - 120) + format_inline("{.time_ago {t}}") + Output + [1] "2 minutes ago" + Code + t <- Sys.time() - 120 + format_inline("{.time_ago {t}}") + Output + [1] "2 minutes ago" + Code + t <- as.POSIXlt(Sys.time() - 120) + format_inline("{.time_ago {t}}") + Output + [1] "2 minutes ago" + diff --git a/tests/testthat/test-inline-2.R b/tests/testthat/test-inline-2.R index 0b9da477..67436653 100644 --- a/tests/testthat/test-inline-2.R +++ b/tests/testthat/test-inline-2.R @@ -212,3 +212,35 @@ test_that(".num", { format_inline("--- {.num {1:4 * 10000}} ---") }) }) + +test_that(".duration", { + expect_snapshot({ + # numeric seconds + format_inline("--- {.duration 0.042} ---") + format_inline("--- {.duration 90} ---") + format_inline("--- {.duration 3661} ---") + + # difftime: units normalised before formatting (not treated as raw seconds) + dt_mins <- as.difftime(1.5, units = "mins") + format_inline("{.duration {dt_mins}}") + + dt_days <- as.difftime(30, units = "days") + format_inline("{.duration {dt_days}}") + }) +}) + +test_that(".time_ago", { + expect_snapshot({ + # numeric unix timestamp + t <- as.numeric(Sys.time() - 120) + format_inline("{.time_ago {t}}") + + # POSIXct + t <- Sys.time() - 120 + format_inline("{.time_ago {t}}") + + # POSIXlt + t <- as.POSIXlt(Sys.time() - 120) + format_inline("{.time_ago {t}}") + }) +})