Unix中的日期时间比较

时间:2014-09-03 06:29:11

标签: unix datetime unix-timestamp

我有两个日期时间字符串,如下所示......

2014-09-03T02:23:09Z2014-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中进行日期时间比较吗?

1 个答案:

答案 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)作为纯数,可以用数字进行比较。

dtcmp.sh

+%s

样本输出

的bash

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 ])
$ 

ksh的

$ 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 ])
$

的zsh

$ 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 ])
$ 

摘要

  • shell都同意ISO 8601日期字符串的纯数字比较不起作用。
  • 只有$ 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,结果一致且正确。
  • 所有shell都使用[[表示法正常工作。

为了获得最大的便携性,请使用expr。为了获得最大的理智,请使用expr