有什么方法可以使用 date 命令或类似命令获取当前 15 分钟间隔吗?
例如,像 date 这样的东西%Y.%m.%d %H:%M
会给我,我需要在从到 的时间范围内2011.02.22 10:19
产生的东西。2011.02.22 10:15
10:15
10:29
答案1
您可以使用 获取当前的 unix 时间戳date "+%s"
,通过一些简单的数学计算找到当前刻钟(我的示例在 中bash
),然后使用更好的格式将其打印回来date
:
curdate=`date "+%s"`
curquarter=$(($curdate - ($curdate % (15 * 60))))
date -d"@$curquarter"
从时间戳设置当前日期和时间的语法@
是 GNU 扩展至日期,如果它不适用于您的操作系统,您可以像这样执行相同的操作(不要忘记指定 UTC,否则,它不会工作):
date -d"1970-01-01 $curquarter seconds UTC"
答案2
以下方法使得无需调用date
两次。
系统调用的开销可能会使“简单”命令比 bash 在其自己的本地环境中执行相同操作慢 100 倍。
更新简单提一下我上面的评论:“慢 100 倍”。现在可以读取“500慢了很多倍”...我最近陷入了(不,是盲目地)这个问题。这是链接:构建测试文件的快速方法
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
[[ "$M" < "15" ]] && M=00 # cater for octal clash
M=$(((M/15)*15))
((M==0)) && M=00 # the math returns 0, so make it 00
echo $Y.$m.$d $H:$M
或者
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
if [[ "$M" < "15" ]] ; then M=00
elif [[ "$M" < "30" ]] ; then M=15
elif [[ "$M" < "45" ]] ; then M=30
else M=45
fi
echo $Y.$m.$d $H:$M
两个版本都只会返回
2011.02.23 01:00
2011.02.23 01:15
2011.02.23 01:30
2011.02.23 01:45
这是第一个对所有 60 个值进行 TEST 循环的循环 {00..59}
for X in {00..59} ; ###### TEST
do ###### TEST
eval $(date +Y=%Y\;m=%m\;d=%d\;H=%H\;M=%M)
M=$X ###### TEST
[[ "$M" < "15" ]] && M=00 # cater for octal clash
M=$(((M/15)*15))
((M==0)) && M=00 # the math returns 0, so make it 00
echo $Y.$m.$d $H:$M
done ###### TEST
答案3
这是在 shell 中处理日期的方法。首先调用date
以获取组件,并用组件填充位置参数($1
、$2
等)(请注意,这是您确实希望$(…)
在双引号之外使用以将字符串分解为单词的罕见情况之一)。然后对组件执行算术、测试或任何您需要执行的操作。最后组装组件。
算术部分可能有点棘手,因为 shell 将其0
视为八进制前缀;例如,这里$(($5/15))
会在整点 8 或 9 分钟时失败。由于最多有一个前导0
,${5#0}
对于算术来说是安全的。添加 100 然后去掉 是1
在输出中获得固定位数的一种方法。
set $(date "+%Y %m %d %H %M")
m=$((100+15*(${5#0}/15)))
last_quarter_hour="$1.$2.$3 $4:${m#1}"
答案4
有些 shell 无需调用外部命令即可完成该工作date
:
克什
a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "#$((a-a%(15*60)))"
巴什 a=$(printf '%(%s)T\n'); printf '%(%Y.%m.%d %H:%M)T\n' "$((a-a%(15*60)))"
桀骜 zmodload zsh/datetime; a=$EPOCHSECONDS; strftime '%Y-%m-%d %H:%M' $((a-a%(15*60)))
以上三个提供本地(非 UTC)时间。如果需要,请使用前导 TZ=UTC0。
ksh 和 bash 语法几乎相同(#
ksh 中所需的除外)。 zsh 需要加载一个模块(包含在 zsh 发行版中)。
也可以使用 (GNU) awk 来完成此操作:
呆呆地 awk 'BEGIN{t=systime();print strftime("%Y.%m.%d %H:%M",t-t%(15*60),1)}'
如果需要本地,这将提供 UTC 结果(将最后一个更改1
为)。0
但是加载外部 awk 或外部 zsh 模块可能与调用 date 本身一样慢:
gnu 日期 a=$(date +%s); date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'
一个小的可执行文件busybox
可以提供类似的结果:
busybox-日期 a=$(busybox date +%s);busybox date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'
请注意,如果 busybox 链接到 PATH 目录中的那些名称,则可以省略前导 busybox 单词。
date
以上两者都busybox date
将打印 UTC 时间。删除-u
当地时间选项。
如果您的操作系统有更有限的日期版本(这是您必须使用的),请尝试:
a=$(date +%s); a=$(( a-a%(15*60) ))
date -d"1970-01-01 $a seconds UTC" +'%Y.%m.%d %H:%M'
或者,如果在 FreeBSD 中,请尝试:
a=$(date +%s); a=$(( a-a%(15*60) ))
date -r "$a" +'%Y.%m.%d %H:%M'