在Bash中,我想计算日期(接收日期)和相对持续时间(保留持续时间)的总和。
例如,让:
reception_date="2017-01-02 12:34:56"
retention_duration="+2 days"
我希望有:
expiration_date="2017-01-04--12-34-56"
请注意,保留期限可以是按日期识别的任何有效相对日期,例如+X weeks
或+X hours
。
我对date
信息页面的第一次掌握使我date
像这样使用
$ date -d '2017-01-02 12:34:56' +'%Y-%m-%d--%H-%M-%S'
2017-01-02--12-34-56
$ date -d '2017-01-02 12:34:56 +1 days' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--12-34-56
$ date -d '2017-01-02 12:34:56 +2 days' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--11-34-56
$ date -d '2017-01-02 12:34:56 +3 days' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--10-34-56
$ date -d '2017-01-02 12:34:56 +4 days' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--09-34-56
$ date -d '2017-01-02 12:34:56 +5 days' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--08-34-56
如您所见,它似乎可以正常使用,+1 days
但是对于更高的值,我得到的结果确实很不规则。
以下示例按预期工作,但可读性差得多:
$ date -d '2017-01-02 +1 days 12:34:56' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--12-34-56
$ date -d '2017-01-02 +2 days 12:34:56' +'%Y-%m-%d--%H-%M-%S'
2017-01-04--12-34-56
$ date -d '2017-01-02 +3 days 12:34:56' +'%Y-%m-%d--%H-%M-%S'
2017-01-05--12-34-56
$ date -d '+1 days 2017-01-02 12:34:56' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--12-34-56
$ date -d '+2 days 2017-01-02 12:34:56' +'%Y-%m-%d--%H-%M-%S'
2017-01-04--12-34-56
$ date -d '+3 days 2017-01-02 12:34:56' +'%Y-%m-%d--%H-%M-%S'
2017-01-05--12-34-56
在理想的解决方案中,我希望拥有:
我不想玩秒转换之类的事情,该解决方案的人类可读性是必不可少的。
谢谢 !
更多信息:
我在使用日期版本的RedHat:
$ date --version
date (GNU coreutils) 8.4
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by David MacKenzie.
在此下游错误报告注释之后,我发现您可以通过添加now
以下内容来做到这一点:
$ date -d '2017-01-02 12:34:56 +2 days' +'%Y-%m-%d--%H-%M-%S'
2017-01-03--05-34-56 ## Oops
$ date -d '2017-01-02 12:34:56 now +2 days' +'%Y-%m-%d--%H-%M-%S'
2017-01-04--12-34-56 ## Much better
在now
防止date
从解析+2
为时区规范 以及一个相对的项目。两者之间的差异已在docs中进行了说明,但在这种情况下解析器显然有些奇怪。我认为从人类的角度来看,“现在”的含义也很奇怪,但可能会更糟!
要查看date
正在执行的操作,请将该--debug
标志添加到您的date
命令中。请参阅下面的完整说明。
至少到目前为止(以及从date
8.26版开始),您必须将相对时间项放置在时间之后。的问题是,+ 1 hour
被解释都为相对时间和作为一个时区(!!!!)。该--debug
到标志date
是你的朋友。
正确行为的示例(cygwin,date
v8.26;添加了我的评论):
$ date --debug -d '+1 hour 2017-01-19 12:34:56' ## Relative before the time
date: parsed relative part: +1 hour(s) ## OK
date: parsed date part: (Y-M-D) 2017-01-19
date: parsed time part: 12:34:56
date: input timezone: -05:00 (set from TZ="America/New_York" environment value) ## Also OK
date: using specified time as starting value: '12:34:56'
date: starting date/time: '(Y-M-D) 2017-01-19 12:34:56 TZ=-05:00'
date: '(Y-M-D) 2017-01-19 12:34:56 TZ=-05:00' = 1484847296 epoch-seconds
date: after time adjustment (+1 hours, +0 minutes, +0 seconds, +0 ns),
date: new time = 1484850896 epoch-seconds
date: output timezone: -05:00 (set from TZ="America/New_York" environment value) ## Still OK
date: final: 1484850896.000000000 (epoch-seconds)
date: final: (Y-M-D) 2017-01-19 18:34:56 (UTC0)
date: final: (Y-M-D) 2017-01-19 13:34:56 (output timezone TZ=-05:00)
Thu, Jan 19, 2017 1:34:56 PM ## A sensible result
错误行为的示例:
$ date --debug -d '2017-01-19 12:34:56 + 1 hour' # +1 hour at the _end_
date: parsed date part: (Y-M-D) 2017-01-19
date: parsed time part: 12:34:56 TZ=+01:00 ## TZ=+1 oops!
date: parsed relative part: +1 hour(s) ## Parsed as a relative part also!
date: input timezone: +01:00 (set from parsed date/time string) ##Oops
date: using specified time as starting value: '12:34:56'
date: starting date/time: '(Y-M-D) 2017-01-19 12:34:56 TZ=+01:00' ##Oops
date: '(Y-M-D) 2017-01-19 12:34:56 TZ=+01:00' = 1484825696 epoch-seconds
date: after time adjustment (+1 hours, +0 minutes, +0 seconds, +0 ns),
date: new time = 1484829296 epoch-seconds
date: output timezone: -05:00 (set from TZ="America/New_York" environment value) ## That's OK
date: final: 1484829296.000000000 (epoch-seconds)
date: final: (Y-M-D) 2017-01-19 12:34:56 (UTC0)
date: final: (Y-M-D) 2017-01-19 07:34:56 (output timezone TZ=-05:00)
Thu, Jan 19, 2017 7:34:56 AM ## Bogus!
我猜您处于UTC + 1时区,因此date(1)解释+1 days
为UTC + 1:00时区并不会伤害您。编辑已报告此错误,gnulib
但似乎未对其进行修补,因此您可能只需要使用已经解决的变通办法即可。好消息是,您不必向用户提供相同的字符串date
。例如,
rel="+2 days"
base="$(date)"
exp="$(date -d "$rel $base")
echo "$base $rel is $exp"
请注意,最后两行交换$base
和的顺序$rel
。
当然,另一种选择是将所有内容都切换为UTC,这样您就可以说date --debug -d '2017-01-19 12:34:56 Z + 1 hour'
(与Z
)来强制将相关部分解释为这样。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句