日期:获取当前的15分钟间隔


15

有什么办法可以使用date命令或类似命令获取当前的15分钟间隔?

例如像日期%Y.%m.%d %H:%M 会给我2011.02.22 10:19,我需要的东西,收益率2011.02.22 10:15从时间跨度10:1510:29

Answers:


17

您可以使用来获取当前的unix时间戳date "+%s",通过一些简单的数学运算来找到当前的四分之一小时(我的示例在中bash),并使用以下更好的格式将其打印回date

curdate=`date "+%s"`
curquarter=$(($curdate - ($curdate % (15 * 60))))
date -d"@$curquarter"

@从时间戳设置当前日期和时间的语法是迄今为止的GNU扩展,如果它在您的OS上不起作用,您可以这样做(不要忘记指定UTC,否则它将不会)工作):

date -d"1970-01-01 $curquarter seconds UTC"

5

以下方法无需调用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 

1
为了澄清起见,“系统调用”是指“ fork / exec / wait,就像system()调用”,而不是一般的系统调用。(我之所以这样说是因为由于用户/内核切换,在系统中进行系统调用也有开销。在这里,这不是特别的问题。)
mattdm

mattdm ...谢谢..我只有6个月的Linux工作经验,所以我很可能使用了错误的短语,但是我一直在阅读有关不必要的电话呼叫所产生的开销以及我自己测试自己的经验。在脚本中,我已经看到了很多示例,其中调用printfor sed以及“不必要的” catvs <file确实会在运行时产生巨大差异。循环时,如我的“慢500倍”示例。。所以,date我的意思是尽可能使用shell并允许诸如批处理之类的程序。Gilles的Left-Pad-0示例,vs printf
Peter.O 2011年

3

这是在Shell中处理日期的一种方法。首先调用date获取组件,并用组件填充位置参数($1$2等)(请注意,这是在少数情况下您确实希望使用$(…)双引号将字符串分解为单词的一种情况)。然后对组件执行算术,测试或任何需要执行的操作。最后组装组件。

算术部分可能有点棘手,因为外壳将其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}"

“交易技巧”……不错。:)
Peter.O 2011年

2

也许不再重要,但是您可以尝试使用我自己的dateutils。四舍五入到分钟是通过dround和一个负参数完成的:

dround now /-15m
=>
  2012-07-11T13:00:00

或遵守您的格式:

dround now /-15m -f '%Y.%m.%d %H:%M'
=>
  2012.07.11 13:00

这真的是您的效用如何工作了吗?使用-15m,我将输入倒数到一个小时后的最近15分钟:不dateutils.dround '2018-11-12 13:55' -15m产生。2018-11-12T13:15:002018-11-12T13:45:00

1
@JackDouglas工具已经发展,现在您想要的是:/-15m即向下舍入到小时数的15分钟的下一个倍数。此功能的语法更加麻烦,因为它接受的值较少,例如/ -13m不可能是因为13并非60的除数(以小时为单位的分钟数)
hroptatyr

很好,现在有了我需要的东西dateutils.dround '2018-11-12 12:52:31' /450s /-15m,谢谢!

2

某些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结果(将最后一个更改10)。但是加载外部awk或外部zsh模块可能与调用日期本身一样慢:

a=$(date +%s); date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'

一个小的可执行文件,例如 busybox可以提供类似的结果:

a=$(busybox date +%s);busybox date -ud "@$((a-a%(15*60)))" +'%Y.%m.%d %H:%M'

请注意,如果busybox链接到PATH目录中的那些名称,则可以省略开头的busybox词。

两者datebusybox 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'

1

如果您可以使用两次调用日期,则此方法可以在Solaris上的bash中使用:

date +"%Y.%m.%d %H:$(( $(date +'%M') / 15 * 15 ))"

代言编辑为:

date +"%Y.%m.%d %H:$(( $(date +'%M') / 15 * 15 ))" | sed 's/:0$/:00/'

1
在小时的第一qurarter,这将产生具有仅单个0,而不是00一输出分钟
Peter.O

更正后,它是在原始命令之后的简单sed。
ddeimeke 2011年

还有一个错误:在H:08和H:10之间无效。请参阅我的答案,了解原因和解决方法。
吉尔(Gilles)“所以,别再邪恶了”,

-1

不确定您的确切要求。但是,如果您想在15分钟后生成时间,则可以使用date -d '+15 min'。输出如下所示:

$ date; date  -d '+15 min'
Tue Feb 22 18:12:39 IST 2011
Tue Feb 22 18:27:39 IST 2011

1
您误解了这个问题。关键是将日期(向下)四舍五入到15分钟。
吉尔斯(Gilles)'所以
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.