我有两个日期时间字符串,如下所示......
2014-09-03T02:23:09Z
和2014-09-03T03:24:57Z
现在,我必须将两个日期时间分配给一些变量并进行比较,如下所示:
d1=2014-09-03T02:23:09Z
d2=2014-09-03T03:24:57Z
if (d1 < d2 )
我浏览了很多网站,但无法找到解决方案。我尝试了下面的方法,但它没有用。
#set -vx
date1=`date -d "2014-09-03T04:27:23Z" +"%Y-%m-%dT%TZ"`
date2=`date -d "2014-09-03T02:23:09Z" +"%Y-%m-%dT%TZ"`
date3=`date -d "2014-09-03T05:23:09Z" +"%Y-%m-%dT%TZ"`
#date1=`date -d "2014-09-03T04:27:23Z"`
#date2=`date -d "2014-09-03T02:23:09Z"`
#date3=`date -d "2014-09-03T05:23:09Z"`
if [ ${date3} -lt ${date1} ] ; then
echo "working"
else
echo "gone"
fi
if [ ${date2} -gt ${date1} ] ; then
echo "working"
else
echo "gone"
fi
我面临以下错误:
sh compare.sh
date: invalid date `2014-09-03T04:27:23Z'
date: invalid date `2014-09-03T02:23:09Z'
date: invalid date `2014-09-03T05:23:09Z'
working
working
有人可以指导我如何在Unix中进行日期时间比较吗?
答案 0 :(得分:3)
当ISO 8601日期格式中的值全部位于同一时区时(Zulu为Z或示例中的UTC),可将其作为字符串进行比较;这是该格式的主要优点之一。
if [ "${date3}" < "${date1}" ]
符号的问题在于您在测试过程中进行输入重定向 - 这不是您想要的。
如果您有Bash,则可以使用[[
代替[
:
if [[ "${date3}" < "${date1}" ]]
或者,您的test
(或[
)命令可以接受:
if [ "${date3}" '<' "${date1}" ]
比较周围的引号阻止它被解释为I / O重定向。
(这适用于Mac OS X 10.9.4,但是再次使用bash
。但/bin/[
也接受它,只要省略尾随]
- 它必须是因为它不是作为[
调用,它要求缺少]
。)POSIX test
不需要支持>
或<
作为运算符 - 仅{{1}字符串比较需要{和=
。
该任务的经典命令是expr
:
!=
这可能是最便携的机制(第7版Unix有if [ $(expr "${date3}" '<' "${date1}") == 1 ]
用于此任务)。它也是最笨拙的符号。
我不清楚您的日期表达本身是否有任何问题,但他们给您expr
错误这一事实表明您可以使用的date: invalid date '2014-09-03T04:27:23Z'
版本不支持符号。它在Ubuntu 14.04上运行正常,date
的版本从date --version
开始。这是一个在date (GNU coreutils) 8.21
运行时适合我的脚本(但不是由bash
运行时 - 因为在Ubuntu上是sh
而不是dash
的符号链接。我使用了bash
(UTC)选项,以便同意输入和输出时间 - 注意可怕的时区。
请注意,如果您使用的是GNU -u
,则可以指定date
以获取自The Epoch(1970-01-01 00:00:00 +00以来)以秒为单位的时间值: 00)作为纯数,可以用数字进行比较。
+%s
date1=`date -u -d "2014-09-03T04:27:23Z" +"%Y-%m-%dT%TZ"`
date2=`date -u -d "2014-09-03T02:23:09Z" +"%Y-%m-%dT%TZ"`
date3=`date -u -d "2014-09-03T05:23:09Z" +"%Y-%m-%dT%TZ"`
if [ ${date3} -lt ${date1} ]
then echo "true (claim: [ $date3 -lt $date1 ])"
else echo "false (claim: [ $date3 -lt $date1 ])"
fi
if [ ${date2} -gt ${date1} ]
then echo "true (claim: [ $date2 -gt $date1 ])"
else echo "false (claim: [ $date2 -gt $date1 ])"
fi
if [ ${date3} '<' ${date1} ]
then echo "true (claim: [ $date3 '<' $date1 ])"
else echo "false (claim: [ $date3 '<' $date1 ])"
fi
if [ ${date2} '>' ${date1} ]
then echo "true (claim: [ $date2 '>' $date1 ])"
else echo "false (claim: [ $date2 '>' $date1 ])"
fi
if [[ ${date3} < ${date1} ]]
then echo "true (claim: [[ $date3 < $date1 ]])"
else echo "false (claim: [[ $date3 < $date1 ]])"
fi
if [[ ${date2} > ${date1} ]]
then echo "true (claim: [[ $date3 > $date1 ]])"
else echo "false (claim: [[ $date3 > $date1 ]])"
fi
if [ $(expr ${date3} '>' ${date1}) = 1 ]
then echo "true (claim: [ \$(expr $date3 '>' $date1) = 1 ])"
else echo "false (claim: [ \$(expr $date3 '>' $date1) = 1 ])"
fi
if [ $(expr ${date2} '>' ${date1}) = 1 ]
then echo "true (claim: [ \$(expr $date2 '>'$date1) = 1 ])"
else echo "false (claim: [ \$(expr $date2 '>' $date1) = 1 ])"
fi
$ bash dtcmp.sh
dtcmp.sh: line 6: [: 2014-09-03T05:23:09Z: integer expression expected
false (claim: [ 2014-09-03T05:23:09Z -lt 2014-09-03T04:27:23Z ])
dtcmp.sh: line 11: [: 2014-09-03T02:23:09Z: integer expression expected
false (claim: [ 2014-09-03T02:23:09Z -gt 2014-09-03T04:27:23Z ])
false (claim: [ 2014-09-03T05:23:09Z '<' 2014-09-03T04:27:23Z ])
false (claim: [ 2014-09-03T02:23:09Z '>' 2014-09-03T04:27:23Z ])
false (claim: [[ 2014-09-03T05:23:09Z < 2014-09-03T04:27:23Z ]])
false (claim: [[ 2014-09-03T05:23:09Z > 2014-09-03T04:27:23Z ]])
true (claim: [ $(expr 2014-09-03T05:23:09Z '>' 2014-09-03T04:27:23Z) = 1 ])
false (claim: [ $(expr 2014-09-03T02:23:09Z '>' 2014-09-03T04:27:23Z) = 1 ])
$
$ dash dtcmp.sh
dtcmp.sh: 6: [: Illegal number: 2014-09-03T05:23:09Z
false (claim: [ 2014-09-03T05:23:09Z -lt 2014-09-03T04:27:23Z ])
dtcmp.sh: 11: [: Illegal number: 2014-09-03T02:23:09Z
false (claim: [ 2014-09-03T02:23:09Z -gt 2014-09-03T04:27:23Z ])
false (claim: [ 2014-09-03T05:23:09Z '<' 2014-09-03T04:27:23Z ])
false (claim: [ 2014-09-03T02:23:09Z '>' 2014-09-03T04:27:23Z ])
dtcmp.sh: 26: dtcmp.sh: [[: not found
false (claim: [[ 2014-09-03T05:23:09Z < 2014-09-03T04:27:23Z ]])
dtcmp.sh: 31: dtcmp.sh: [[: not found
false (claim: [[ 2014-09-03T05:23:09Z > 2014-09-03T04:27:23Z ]])
true (claim: [ $(expr 2014-09-03T05:23:09Z '>' 2014-09-03T04:27:23Z) = 1 ])
false (claim: [ $(expr 2014-09-03T02:23:09Z '>' 2014-09-03T04:27:23Z) = 1 ])
$
$ ksh dtcmp.sh
dtcmp.sh[6]: [: 2014-09-03T05:23:09Z: arithmetic syntax error
false (claim: [ 2014-09-03T05:23:09Z -lt 2014-09-03T04:27:23Z ])
dtcmp.sh[11]: [: 2014-09-03T02:23:09Z: arithmetic syntax error
false (claim: [ 2014-09-03T02:23:09Z -gt 2014-09-03T04:27:23Z ])
dtcmp.sh[16]: [: <: unknown operator
false (claim: [ 2014-09-03T05:23:09Z '<' 2014-09-03T04:27:23Z ])
false (claim: [ 2014-09-03T02:23:09Z '>' 2014-09-03T04:27:23Z ])
false (claim: [[ 2014-09-03T05:23:09Z < 2014-09-03T04:27:23Z ]])
false (claim: [[ 2014-09-03T05:23:09Z > 2014-09-03T04:27:23Z ]])
true (claim: [ $(expr 2014-09-03T05:23:09Z '>' 2014-09-03T04:27:23Z) = 1 ])
false (claim: [ $(expr 2014-09-03T02:23:09Z '>' 2014-09-03T04:27:23Z) = 1 ])
$
$ zsh dtcmp.sh
dtcmp.sh:[:6: integer expression expected: 2014-09-03T05:23:09Z
false (claim: [ 2014-09-03T05:23:09Z -lt 2014-09-03T04:27:23Z ])
dtcmp.sh:[:11: integer expression expected: 2014-09-03T02:23:09Z
false (claim: [ 2014-09-03T02:23:09Z -gt 2014-09-03T04:27:23Z ])
dtcmp.sh:16: condition expected: <
false (claim: [ 2014-09-03T05:23:09Z '<' 2014-09-03T04:27:23Z ])
dtcmp.sh:21: condition expected: >
false (claim: [ 2014-09-03T02:23:09Z '>' 2014-09-03T04:27:23Z ])
false (claim: [[ 2014-09-03T05:23:09Z < 2014-09-03T04:27:23Z ]])
false (claim: [[ 2014-09-03T05:23:09Z > 2014-09-03T04:27:23Z ]])
true (claim: [ $(expr 2014-09-03T05:23:09Z '>' 2014-09-03T04:27:23Z) = 1 ])
false (claim: [ $(expr 2014-09-03T02:23:09Z '>' 2014-09-03T04:27:23Z) = 1 ])
$
接受并正常使用普通bash
又名'<'
中的'>'
和test
运算符 - 其他shell不接受或接受它但产生了错误的答案(更糟糕的是!)。[
的shell,结果一致且正确。[[
表示法正常工作。为了获得最大的便携性,请使用expr
。为了获得最大的理智,请使用expr
。