如何在脚本中显示星期、天和小时

如何在脚本中显示星期、天和小时

这是先前的问题关于bash我编写的一个脚本,它可以帮助我更准确地跟踪我的恶习。我现在正在尝试修改该脚本以显示所有非零单位:

It's been 2 weeks, 1 day and 5 hours since you last bought a deck.

为此,以下是我迄今为止编写的脚本的相关部分:

last_bought=$(cat "$lb_file") # file contains time in epoch seconds
...
now=$(date -u +%s)
elapsed="$((now-last_bought))"
W=$((elapsed/60/60/24/7))
D=$((elapsed/60/60/24))
H=$((elapsed/60/60%24))
if [[ $W -le 0 && $D -le 0 && $H -gt 0 ]]; then string="$H hours"
elif [[ $W -le 0 && $D -gt 0 && $H -gt 0 ]]; then string="$D days and $H hours"
elif [[ $W -gt 0 && $D -gt 0 && $H -le 0 ]]; then string="$W weeks and $D days"
elif [[ $W -gt 0 && $D -le 0 && $H -gt 0 ]]; then string="$W weeks and $H hours"
elif [[ $W -gt 0 && $D -gt 0 && $H -gt 0 ]]; then string="$W weeks, $D days and $H hours"
fi

这对于小时和天数来说非常有效(运行脚本时,小时值为-b 50shows 2 days and 2 hours)。但是,当脚本中输入的小时值至少为一周时,两个都$W和变量$D已填充。这意味着对于 (1 周的小时数) 的值-b 168,输出将为:

It's been 1 weeks and 7 days since you last bought a deck.

我该如何解决这个问题,最好同时实现单数时间段,如下所示:

It's been 1 week and 1 hour since you last bought a deck.

我也意识到我可能以一种非常粗略的方式检查我的逻辑,所以如果有更聪明/更常见的方法,我将不胜感激,并且

答案1

now=$(date +%s)
last_bought=$(date -d '-1 week -3 days -6 hours -34 minutes' +%s)

elapsed=$(( (now - last_bought) / 3600))     # truncate to hours
((hrs   = elapsed % 24, elapsed /= 24))
((days  = elapsed % 7))
((weeks = elapsed / 7))
echo "$weeks weeks, $days days, $hrs hours"
1 weeks, 3 days, 6 hours

答案2

乍一看,我认为问题在于您正在使用整个经过的时间来评估 W、D、H。

每次评估后,您都应该减少elapsed该金额。

日期和小时似乎可以正常工作而无需减少的情况最有可能是因为 H 是使用模 24 进行评估的。

还要记住,由于闰年、闰月、夏令时、日历翻转等,日期操作更加复杂。

从片段和明显的用途来看,数学可能已经足够好了。

答案3

之后很多反复试验并查找文档对于bash非常令人困惑的变量运算符(=/=*等等),我设法调整了Glenn的答案,使其对我有用:

now=$(date +%s)
last_bought=$(date -u +%s)
elapsed=$(((now-last_bought) / 3600))
H=$((elapsed % 24))
D=$(( ( elapsed /= 24 ) % 7))
W=$((elapsed / 7))
echo "$H weeks, $D days, $H hours"

我仍然不完全确定我是否理解变量运算符的工作原理,但无论如何,代码现在似乎按我想要的方式工作。

相关内容