在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.
答案 0 :(得分:2)
从this downstream bug-report comment开始,我发现您可以通过添加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
解析为时区规范 以及 相对项< / strong>即可。两者之间的差异在the docs中解释,但在这种情况下,解析器显然有点奇怪。我想&#34;现在&#34;从人的角度来看也很奇怪,但可能更糟糕!
要查看date
正在做什么,请在--debug
命令中添加date
标志。请参阅下面的完整说明。
至少截至目前(仍然是date
版本8.26),您必须将相对时间项目放在除时间之外的其他位置。问题是+ 1 hour
被解释为两者作为相对时间和作为时区(!!!!)。 --debug
的{{1}}标记是您的朋友。
正确行为示例(cygwin,date
v8.26;我的评论已添加):
date
错误行为的示例:
$ 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
我猜你在UTC + 1时区,所以date(1)将$ 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:00时区并没有伤害你。 修改此has been reported到gnulib
但似乎没有修补,因此您可能只需要使用已经遇到的解决方法。好消息是,您不必向用户+1 days
提供相同的字符串。例如,
date
请注意rel="+2 days"
base="$(date)"
exp="$(date -d "$rel $base")
echo "$base $rel is $exp"
和$base
的顺序在最后两行中交换。
另一种选择当然是将所有内容切换为UTC,以便您可以说$rel
(使用date --debug -d '2017-01-19 12:34:56 Z + 1 hour'
)来强制相关部分被解释为。