Unix 中的日期时间比较

2024-02-14

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

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 中进行日期时间比较吗?


当 ISO 8601 日期格式的值都位于同一时区时(示例中的 Z 代表 Zulu 或 UTC),可以将它们作为字符串进行比较;这是该格式的主要优点之一。

问题在于if [ "${date3}" < "${date1}" ]表示法是您在测试过程中进行输入重定向 - 这不是您想要的。

如果你有 Bash,你可以使用[[代替[:

if [[ "${date3}" < "${date1}" ]]

或者,您的test (or [) 命令可以接受:

if [ "${date3}" '<' "${date1}" ]

比较周围的引号可防止将其解释为 I/O 重定向。 (这适用于 Mac OS X 10.9.4,但这是使用bash再次。然而,/bin/[也接受它,只要我省略尾随]— 一定是因为它没有被调用为[它需要不存在].) POSIXtest http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html不需要支持> or <作为运营商——仅= and !=需要进行字符串比较。

该任务的经典命令是expr http://pubs.opengroup.org/onlinepubs/9699919799/utilities/expr.html:

if [ $(expr "${date3}" '<' "${date1}") == 1 ]

这可能是最可移植的机制(第七版 Unix 有expr对于这个任务)。这也是最笨拙的表示法。


更新的问题

我不清楚你的日期表达式本身有什么问题,但事实上它们给了你date: invalid date '2014-09-03T04:27:23Z'错误表明版本date您可用的不支持该符号。它在 Ubuntu 14.04 上运行正常,版本为date --version开始date (GNU coreutils) 8.21。这是一个运行时对我有用的脚本bash(但不是当运行时sh——因为在 Ubuntu 上这是一个符号链接dash而不是bash)。我用的是-u(UTC) 选项,以便输入和输出时间一致——小心可怕的时区。

请注意,如果您使用的是 GNUdate,您可以指定+%s获取自纪元(即 1970-01-01 00:00:00 +00:00)以来的时间值(以秒为单位)作为纯数字,并且可以对它们进行数字比较。

dtcmp.sh

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

$ 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

$ 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

$ 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

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

Summary

  • shell 都同意 ISO 8601 日期字符串的纯数字比较不起作用。
  • Only bash接受并正确使用'<' and '>'简单的运算符test aka [— 其他 shell 要么不接受它,要么接受它但产生错误的答案(这更糟糕!)。
  • 对于支持的 shell[[,结果一致且正确。
  • 所有 shell 都可以正常工作expr符号。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unix 中的日期时间比较 的相关文章

  • 创建 jar 文件 - 保留文件权限

    我想知道如何创建一个保留其内容的文件权限的 jar 文件 我将源代码和可执行文件打包在一个 jar 文件中 该文件将在使用前提取 人们应该能够通过运行批处理 shell 脚本文件立即运行示例和演示 然后他们应该能够修改源代码并重新编译所有内
  • 将时间添加到日期时间

    我有一个像这样的日期字符串 然后使用strptime 所以就像这样 my time datetime datetime strptime 07 05 15 m d Y 现在我想添加 23 小时 59 分钟my time 我努力了 timed
  • 抑制 makefile 中命令调用的回显?

    我为一个作业编写了一个程序 该程序应该将其输出打印到标准输出 分配规范需要创建一个 Makefile 当调用它时make run gt outputFile应该运行该程序并将输出写入一个文件 该文件的 SHA1 指纹与规范中给出的指纹相同
  • 如何在 shell 脚本中操作 $PATH 元素?

    有没有一种惯用的方法从类似 PATH 的 shell 变量中删除元素 这就是我想要的 PATH home joe bin usr local bin usr bin bin path to app bin and remove or rep
  • 无法从 jenkins 作为后台进程运行 nohup 命令

    更新 根据下面的讨论 我编辑了我的答案以获得更准确的描述 我正在尝试从詹金斯运行 nohup 命令 完整的命令是 nohup java jar home jar server process 0 35 jar prod gt gt var
  • 如何有效截断文件头?

    大家都知道truncate file size 函数 通过截断文件尾部将文件大小更改为给定大小 但是如何做同样的事情 只截断文件的尾部和头部呢 通常 您必须重写整个文件 最简单的方法是跳过前几个字节 将其他所有内容复制到临时文件中 并在完成
  • awk/Unix 分组依据

    有这个文本文件 name age joe 42 jim 20 bob 15 mike 24 mike 15 mike 54 bob 21 试图得到这个 计数 joe 1 jim 1 bob 2 mike 3 Thanks awk F NR
  • 类型错误:“datetime.datetime”和“str”的实例之间不支持“>”

    我是 python 日期和时间类型的新手 我有一个日期值 date 2018 11 10 10 55 31 00 00 我需要检查该日期值是否超过 90 天 我试过 from datetime import datetime from da
  • 如何使用非标准的一周第一天在 Oracle 中计算一年中的第几周?

    我有一个查询需要返回日期字段的 一年中的第几周 但查询的客户使用非标准的一周第一天 所以TO CHAR with IW 没有返回预期的结果 在这种情况下 一周的第一天是周六 周五是一周的第七天 对于 T SQL 我会使用DATEPART a
  • 如何在jquery中获取保存时间和当前时间的差异?

    我想在 javascript 或 jquery 中获取保存时间和当前时间之间的时差 我节省的时间看起来像Sun Oct 24 15 55 56 GMT 05 30 2010 java中的日期格式代码如下 String newDate 201
  • 是否可以创建一个脚本来保存和恢复权限?

    我正在使用 Linux 系统 需要对一组嵌套文件和目录进行一些权限实验 我想知道是否没有某种方法可以保存文件和目录的权限 而不保存文件本身 换句话说 我想保存权限 编辑一些文件 调整一些权限 然后将权限恢复到目录结构中 将更改的文件保留在适
  • 使用 datetime 与 Django 中的日期进行比较

    我在 Django 中有一个关于如何比较日期来解决一些解决方案的问题 例如 我的 models py 中有一个日期字段 如下所示 class Invoice models Model payment date models DateTime
  • C# 中将字符串 (yyyyMMddhhmm) 转换为 DateTime 的函数

    在我的数据库中 我有一个日期类型的字段varchar其中日期以以下格式存储yyyyMMddhhmm 没有空格或其他字符分隔它们 现在我需要将此日期与 C 进行比较DateTime 因此我需要将字符串转换为DateTime 我能想到的最合乎逻
  • waitpid() 的作用是什么?

    有什么用waitpid 它通常用于等待特定进程完成 或者如果您使用特殊标志则更改状态 基于其进程 ID 也称为pid 它还可用于等待一组子进程中的任何一个 无论是来自特定进程组的子进程还是当前进程的任何子进程 See here http l
  • 如何在unix中移动或复制“find”命令列出的文件?

    我有使用下面的命令看到的某些文件的列表 但是如何将列出的这些文件复制到另一个文件夹 例如 test 中 find mtime 1 exec du hc 添加到 Eric Jablow 的答案中 这是一个可能的解决方案 它对我有用 linux
  • 使用 php 和 mysql 计算日期差(以小时为单位)

    我如何使用 php 和 mysql 找到以小时为单位的日期差异 Use TIMEDIFF http dev mysql com doc refman 5 1 en date and time functions html function
  • 绘制持续时间图表

    从我在写这篇文章之前所做的阅读中 我相当确定我需要创建甘特图 但我不知道这是否是正确的路线 需要将开始时间和结束时间的数据作为一个单位绘制在 Excel 图表上 Y 轴为日期 X 轴为一天中的小时 开始时间和结束时间的格式是 Excel 数
  • UNTimeIntervalNotificationTrigger nextTriggerDate() 是否给出了错误的日期?

    我正在更新本地通知以与 iOS 10 配合使用 但遇到了一个问题 我认为 nextTrigger 函数返回的不是 满足触发条件的下一个日期 而是返回当前日期时间加上您最初设置 UNTimeInvervalNotificationTrigge
  • 如何编写一个 SQL 查询来计算每月和每年的行数?

    有谁知道如何查询 vbulletin 数据库来生成每月 每年注册数量的报告 以获得如下结果 MM YYYY Count 01 2001 10 02 2001 12 感谢下面的这些答案 我的最终版本有效如下 SELECT COUNT as R
  • 在 C++20 中获取当前日期/时间是线程安全的吗?

    简短的问题 在 C 17 之前 包括 C 17 C 不提供线程安全的方式来获取当前时间或日期 这个问题会在 C 20 中修复吗 长问题 获取当前时间和日期的唯一可移植方法是使用 std gmtime 或 std localtime 函数 这

随机推荐