From 59ff4d042ea4db533198bf977248c7d40a7f4067 Mon Sep 17 00:00:00 2001 From: Wei-Lun Li Date: Fri, 6 Nov 2026 13:40:48 +0000 Subject: [PATCH] fix(timer): round duration before splitting off minutes (#14246) --- plugins/timer/tests/timer.test.zsh | 39 ++++++++++++++++++++++++++++++ plugins/timer/timer.plugin.zsh | 10 ++++++-- 2 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 plugins/timer/tests/timer.test.zsh diff --git a/plugins/timer/tests/timer.test.zsh b/plugins/timer/tests/timer.test.zsh new file mode 100644 index 000000000..d0184ac97 --- /dev/null +++ b/plugins/timer/tests/timer.test.zsh @@ -0,0 +1,39 @@ +#!/usr/bin/env zsh + +# Run with: zsh -df plugins/timer/tests/timer.test.zsh +emulate -L zsh + +source "${0:A:h:h}/timer.plugin.zsh" + +typeset -i failures=0 tests=0 + +check_duration() { + local precision=$1 duration=$2 expected=$3 + local output=$(TIMER_PRECISION=$precision __timer_format_duration $duration) + (( tests++ )) + + if [[ $output == "$expected" ]]; then + print -r -- "PASS: $duration with precision $precision -> $output" + else + print -u2 -r -- "FAIL: $duration with precision $precision -> $output (expected $expected)" + (( failures++ )) + fi +} + +check_duration 1 0.04 /0.0s +check_duration 1 3.04 /3.0s +check_duration 1 40.0 /40.0s +check_duration 1 59.94 /59.9s +check_duration 1 59.97 /1m0.0s +check_duration 1 61.5 /1m1.5s +check_duration 1 73.0 /1m13.0s +check_duration 1 119.97 /2m0.0s +check_duration 1 3599.99 /60m0.0s +check_duration 2 59.996 /1m0.00s +check_duration 2 0.02 /0.02s +check_duration 0 1.4 /1s +check_duration 0 59.6 /1m0s +check_duration 0 119.5 /2m0s + +print -r -- "$tests tests, $failures failures" +(( failures == 0 )) diff --git a/plugins/timer/timer.plugin.zsh b/plugins/timer/timer.plugin.zsh index 6baf1f681..22f17052f 100644 --- a/plugins/timer/timer.plugin.zsh +++ b/plugins/timer/timer.plugin.zsh @@ -6,8 +6,14 @@ __timer_current_time() { } __timer_format_duration() { - local mins=$(printf '%.0f' $(($(IFS='.' read int dec <<< "$1"; echo $int) / 60))) - local secs=$(printf "%.${TIMER_PRECISION:-1}f" $(($1 - 60 * mins))) + local -i precision=${TIMER_PRECISION:-1} + local -i scale=$(( 10 ** precision )) + # Round to the displayed precision before splitting off the minutes, + # so that e.g. 59.97s is shown as 1m0.0s instead of 60.0s + local -i units + (( units = $1 * scale + 0.5 )) + local -i mins=$(( units / (60 * scale) )) + local secs=$(printf "%.${precision}f" $(( (units - 60 * scale * mins) / (scale * 1.0) ))) local duration_str=$(echo "${mins}m${secs}s") local format="${TIMER_FORMAT:-/%d}" echo "${format//\%d/${duration_str#0m}}"