Shell 日期:非法选项--d,查找两个日期之间的差异
我试图将从文件中读取的时间戳从字符串格式转换为日期格式,以便找到2个日期/时间戳的差异。web上的大多数线程/讨论都使用日期参数'-d'将字符串转换为历元或查找两个时间戳的差异 但我的环境/操作系统似乎不支持-d日期参数。以下是my env的详细信息:Shell 日期:非法选项--d,查找两个日期之间的差异,shell,unix,sunos,Shell,Unix,Sunos,我试图将从文件中读取的时间戳从字符串格式转换为日期格式,以便找到2个日期/时间戳的差异。web上的大多数线程/讨论都使用日期参数'-d'将字符串转换为历元或查找两个时间戳的差异 但我的环境/操作系统似乎不支持-d日期参数。以下是my env的详细信息: bash --version GNU bash, version 3.2.52(1)-release (i386-pc-solaris2.10) Copyright (C) 2007 Free Software Foundation, Inc.
bash --version
GNU bash, version 3.2.52(1)-release (i386-pc-solaris2.10)
Copyright (C) 2007 Free Software Foundation, Inc.
uname -a
SunOS s01***** 5.10 Generic_147148-26 i86pc i386 i86pc
从文件中读取的示例日期:
START_TIME="09/03/16 - 01:04:56"
END_TIME="09/03/16 - 05:10:44"
我尝试过的代码
我试着模仿下面的代码
我不认为第5行的语法错误是罪魁祸首,因为我没有在约会对象的手册页中找到选项-d
针对评论:
>>> date --version
date: illegal option -- version
usage: date [-u] mmddHHMM[[cc]yy][.SS]
date [-u] [+format]
date -a [-]sss[.fff]
>>> date --help
date: illegal option -- help
usage: date [-u] mmddHHMM[[cc]yy][.SS]
date [-u] [+format]
date -a [-]sss[.fff]
>>> echo $0
bash
甚至这些参数也不受支持。如果我犯了愚蠢的错误,我会道歉
有没有人能给我一个与上面分享的环境细节相当的-d,或者一个不用-d就可以找出两个日期之间差异的方法
提前感谢根据POSIX标准,
日期
不会为您计算日期和时间。它获取或设置系统日期和时间,可能带有时区调整。请参阅并注意缺少-d
选项(或者任何有趣的选项!)
问题变成了“如果没有date
,我们如何计算日期和时间?”您提供的时间戳没有时区信息,因此通常的行为是假设当地时间。当地时间是。认真地一些时区在数百年前已经存在或没有意义(例如,大多数美国时区)。因此,虽然您可能能够在最近的一段时间内拼凑出一个适用于您所在地区的定制解决方案,但它并不健壮
如果可以将时间戳转换为Unix时间,只需减去它们,就可以得到正确的答案。不幸的是,据我所知,这不能在命令行中完成。Unix提供了从C执行此操作的功能(从C开始,您可以继续,如中所示),但我不相信有任何完全标准的实用程序为此提供命令行界面。您可能需要自己编写和编译
纠正闰秒是非常困难的,因为据我所知,POSIX从来没有提供一个标准接口来找出过去发生闰秒的时间。这样的接口需要互联网连接才能保持最新,这对于许多实现来说可能都不是第一步。如果不了解更多关于您的系统及其功能的信息,我就无法猜测什么对您的用例起作用或不起作用。
awk
mktime
很有可能存在于您的系统上:
#!/bin/bash
START_TIME="09/03/16 - 01:04:56"
END_TIME="09/03/16 - 05:10:44"
echo -e "$START_TIME\n$END_TIME" |
tr '/:-' ' ' |
awk '{print "20"$3" "$2" "$1" "$4" "$5" "$6}' |
awk '{printf "%s ", mktime($0)}' |
awk '{print $2 - $1}'
说明:
echo
两个时间字符串tr
将09/03/16-01:04:56
转换为09 03 16:04:56
awk
将09 03 16 01 04 56
更改为2016 03 09 01 04 56
awk
将2016 03 09 01 04 56
转换为纪元时间:1457514296
并在一行上同时打印:1457514296 1457529044
awk
从第二个减去第一个,以秒为单位给出差值:14748
awk
s也可以很容易地合并,但为了清晰起见,这里我将每个单独保存。IMHO,更好地发布date--version
和date--help
(date--help | fgrep--d
以获得更短的输出)而不是bash--version
。或者,除了bash--version
,您还可以发布实际错误吗。请看:bash版本完全不相关——任何版本的bash都会有这个问题,或者根本不使用bash。(既然你可以在没有bash的情况下重现问题,bash
标签在这个问题上做了什么?)你好,Cyrus,谢谢你的建议。我最初是从perl开始这项任务的,并意识到像“date”、“Time”等大多数perl日期模块在我的机器上都不可用。因此,我被迫切换到bash.mktime,并且可能不存在于OP的awk
下。嗨,韦伯,感谢您的逐步演练,我已经理解了您的建议,但当我尝试模拟相同的代码时,结果很烦人。对于开始时间和结束时间的任何值,我都得到相同的结果“2013”。即使两个时间戳完全相同。然后我意识到,第三个awk是“2016-03=2013”,而不是“结束时间-开始时间”。我想,正如凯文所说,我的环境不支持mktime。有什么克服这个问题的建议吗?谢谢。首先,如果您的系统中存在的问题,请尝试使用gawk
而不是awk
。否则,就有一个次优的解决方案,就是用分钟域乘以60,小时乘以60*60,天乘以60*60*24,月乘以。。。好吧,有一个if
语句,每月乘以该月的秒数。。。然后将年份字段乘以365.25*24*60*60。
#!/bin/bash
START_TIME="09/03/16 - 01:04:56"
END_TIME="09/03/16 - 05:10:44"
echo -e "$START_TIME\n$END_TIME" |
tr '/:-' ' ' |
awk '{print "20"$3" "$2" "$1" "$4" "$5" "$6}' |
awk '{printf "%s ", mktime($0)}' |
awk '{print $2 - $1}'