Dateutils 是一组围绕在命令行上处理日期和时间的工具,重点关注处理大量财务数据时出现的用例。
Dateutils 主要托管在 github 上:
github页面:https://github.com/hroptatyr/dateutils
项目主页:http://www.fresse.org/dateutils/
下载:https://bitbucket.org/hroptatyr/dateutils/downloads
下面是一个简短的示例列表,演示了 dateutils 的功能,有关完整规范,请参阅信息和手册页。 有关安装说明,请参阅安装文件。
Dateutils 命令以date
为前缀,但出于直觉原因,其他方面类似于已知的 UNIX 命令。 唯一的例外是strptime
,它类似于同名的 libc 函数。
strptime
C 函数的命令行版本
dateadd
将持续时间添加到日期或时间
dateconv
在日历之间转换日期或时间
datediff
计算日期或时间之间的持续时间
dategrep
Grep 输入流中的日期或时间
dateround
将日期或时间舍入为“更完整”的值
dateseq
生成日期或时间序列
datesort
按时间顺序排序。
datetest
比较日期或时间
datezone
批量将日期/时间转换为时区
我喜欢通过例子解释一切以获得第一印象。所以它来了。
模仿 seq(1) 的工具,但其输入来自日期域而不是整数。 通常脚本使用类似的东西
$ for i in $(seq 0 9); do date -d "2010-01-01 +${i} days" "+%F" done
现在可以缩短为
$ dateseq 2010-01-01 2010-01-10
另一个好处是可以直接给出结束日期,而不是根据开始日期和天数间隔计算。 此外,它还提供了特定于日期的功能,这些功能将成为使用上述 seq(1)/date(1) 方法实现的 PITA,例如跳过某些工作日:
$ dateseq 2010-01-01 2010-01-10 --skip sat,sun => 2010-01-01 2010-01-04 2010-01-05 2010-01-06 2010-01-07 2010-01-08
dateeq 也适用于时间:
$ dateseq 12:00:00 5m 12:17:00 => 12:00:00 12:05:00 12:10:00 12:15:00
还有日期时间:
$ dateseq --compute-from-last 2012-01-02T12:00:00 5m 2012-01-02T12:17:00 => 2012-01-02T12:02:00 2012-01-02T12:07:00 2012-01-02T12:12:00 2012-01-02T12:17:00
一种在不同历法系统和/或时区之间转换日期的工具。 其他此类工具通常侧重于将公历日期转换为中国历法,而 dconv 旨在支持在金融环境中至关重要的日历系统。
要将(公历)日期转换为所谓的 ymcw 表示形式:
$ dateconv 2012-03-04 -f "%Y-%m-%c-%w" => 2012-03-01-00
反之亦然:
$ dateconv 2012-03-01-Sun -i "%Y-%m-%c-%a" -f '%F' => 2012-03-04
其中 ymcw 表示表示给定年份中第%c
个月的%w
。 如果指定日期(例如五月的第三个星期四),这非常有用。
dateconv 还可以用于动态转换输入流中出现的日期、时间或日期时间
$ dateconv -S -i '%b/%d %Y at %I:%M %P' <<EOF Remember we meet on Mar/03 2012 at 02:30 pm EOF => Remember we meet on 2012-03-03T14:30:00
最重要的是在时区之间进行转换:
$ dateconv --from-zone "America/Chicago" --zone "Asia/Tokyo" 2012-01-04T09:33:00 => 2012-01-05T00:33:00 $ dateconv --zone "America/Chicago" now -f "%d %b %Y %T" => 05 Apr 2012 11:11:57
一个在 shell 中执行日期比较的工具,它是在test(1)
之后建模的,但具有适当的命令行选项。
$ if datetest today --gt 2010-01-01; then echo "yes" fi => yes
在 shell 中执行日期算术(date maths)的工具。 给定一个日期和一个持续时间列表,这将计算新的日期。 给定持续时间和日期列表,这将计算新日期。
$ dateadd 2010-02-02 +4d => 2010-02-06 $ dateadd 2010-02-02 +1w => 2010-02-09 $ dateadd -1d <<EOF 2001-01-05 2001-01-01 EOF => 2001-01-04 2000-12-31
将持续时间添加到时间中:
$ dateadd 12:05:00 +10m => 12:15:00
甚至日期时间:
$ dateadd 2012-03-12T12:05:00 -1d4h => 2012-03-11T08:05:00
如果系统的 zoneinfo 数据库支持,则可以进行闰秒调整计算。 使用单位rs
表示“真实”秒:
$ dateadd '2012-06-30 23:59:30' +30rs => 2012-06-30T23:59:60
与以下相反:
$ dateadd '2012-06-30 23:59:30' +30s => 2012-07-01T00:00:00
计算两个(或多个)日期之间差异的工具。 这有点与爸爸相反。 输出将是持续时间,当添加到第一个日期时,将给出第二个日期。
获取两个日期之间的天数:
$ datediff 2001-02-08 2001-03-02 => 22
持续时间格式可以通过-f
开关控制:
$ datediff 2001-02-08 2001-03-09 -f "%m month and %d day" => 1 month and 1 day
datediff 还接受时间戳作为输入:
$ datediff 2012-03-01T12:17:00 2012-03-02T14:00:00 => 92580s
-f
开关做了正确的事情:
$ datediff 2012-03-01T12:17:00 2012-03-02T14:00:00 -f '%dd %Ss' => 1d 6180s
比较:
$ datediff 2012-03-01T12:17:00 2012-03-02T14:00:00 -f '%dd %Hh %Ss' => 1d 1h 2580s
如果系统的zoneinfo数据库支持的话,可以进行闰秒调整计算。 使用格式说明符%rS
获取以“真实”秒为单位的经过时间:
datediff '2012-06-30 23:59:30' '2012-07-01 00:00:30' -f '%rS' => 61
一种从输入流中提取符合特定条件的行的工具,显示行或匹配项:
$ dategrep '<2012-03-01' <<EOF Feb 2012-02-28 Feb 2012-02-29 leap day Mar 2012-03-01 Mar 2012-03-02 EOF => Feb 2012-02-28 Feb 2012-02-29 leap day
一种将日期或时间戳“四舍五入”到重复出现的时间点的工具,例如下一个/上一个一月或下一个/上一个星期四。
四舍五入(向后)到当月的第一天:
$ dateround '2011-08-22' -1 => 2011-08-01
查找当前日期(今天是 2016-01-08)的下一个星期一:
$ dateround today Mon => 2015-01-11
回到去年九月,然后四舍五入到月底:
$ dateround today -- -Sep +31d => 2015-09-30
将日期流严格舍入到下个月的第一天:
$ dateround -S -n 1 <<EOF pay cable 2012-02-28 pay gas 2012-02-29 pay rent 2012-03-01 redeem loan 2012-03-02 EOF => pay cable 2012-03-01 pay gas 2012-03-01 pay rent 2012-04-01 redeem loan 2012-04-01
将时间序列舍入到下一分钟(即秒部分为 00),然后舍入到下一个半点时间(并转换为 ISO):
$ dateround -S 0s30m -i '%d/%m/%Y %T' -f '%F %T' <<EOF 06/03/2012 14:27:12 eventA 06/03/2012 14:29:59 eventA 06/03/2012 14:30:00 eventB 06/03/2012 14:30:01 eventB EOF => 2012-03-06 14:30:00 eventA 2012-03-06 14:30:00 eventA 2012-03-06 14:30:00 eventB 2012-03-06 15:30:00 eventB
或者,如果您将一天分为半小时,您可以使用 co-class 表示法四舍五入到其中一个:
$ dateround -S /30m -i '%d/%m/%Y %T' -f '%F %T' <<EOF 06/03/2012 14:27:12 eventA 06/03/2012 14:29:59 eventA 06/03/2012 14:30:00 eventB 06/03/2012 14:30:01 eventB EOF => 2012-03-06 14:30:00 eventA 2012-03-06 14:30:00 eventA 2012-03-06 14:30:00 eventB 2012-03-06 15:00:00 eventB
这与前面的示例基本相同,只是整小时(半小时的偶数倍)是可能的舍入目标。
一种按时间顺序排列文件行的工具。
目前, datesort
工具依赖于支持字段的sort(1)
,特别是-t
选择分隔符和-k
按特定字段排序。
$ datesort <<EOF 2009-06-03 caev="DVCA" secu="VOD" exch="XLON" xdte="2009-06-03" nett/GBX="5.2" 2011-11-16 caev="DVCA" secu="VOD" exch="XLON" xdte="2011-11-16" nett/GBX="3.05" 2013-11-20 caev="DVCA" secu="VOD" exch="XLON" xdte="2013-11-20" nett/GBX="3.53" 2012-06-06 caev="DVCA" secu="VOD" exch="XLON" xdte="2012-06-06" nett/GBX="6.47" 2013-06-12 caev="DVCA" secu="VOD" exch="XLON" xdte="2013-06-12" nett/GBX="6.92" 2010-11-17 caev="DVCA" secu="VOD" exch="XLON" xdte="2010-11-17" nett/GBX="2.85" EOF => 2009-06-03 caev="DVCA" secu="VOD" exch="XLON" xdte="2009-06-03" nett/GBX="5.2" 2010-11-17 caev="DVCA" secu="VOD" exch="XLON" xdte="2010-11-17" nett/GBX="2.85" 2011-11-16 caev="DVCA" secu="VOD" exch="XLON" xdte="2011-11-16" nett/GBX="3.05" 2012-06-06 caev="DVCA" secu="VOD" exch="XLON" xdte="2012-06-06" nett/GBX="6.47" 2013-06-12 caev="DVCA" secu="VOD" exch="XLON" xdte="2013-06-12" nett/GBX="6.92" 2013-11-20 caev="DVCA" secu="VOD" exch="XLON" xdte="2013-11-20" nett/GBX="3.53"
快速检查不同时区的日期/时间值的工具。结果将是一个显示每个时区的每个日期时间值的矩阵:
$ datezone Europe/Berlin Australia/Sydney now 2014-06-30T05:00:00 => 2014-01-30T17:37:13+01:00 Europe/Berlin 2014-01-31T03:37:13+11:00 Australia/Sydney 2014-06-30T07:00:00+02:00 Europe/Berlin 2014-06-30T15:00:00+10:00 Australia/Sydney
datezone
工具还可用于获取相对于给定日期/时间的下一个或上一个 DST 转换:
$ datezone --next Europe/Berlin Australia/Sydney 2013-02-19 => 2013-03-31T02:00:00+01:00 -> 2013-03-31T03:00:00+02:00 Europe/Berlin 2013-04-07T03:00:00+11:00 -> 2013-04-07T02:00:00+10:00 Australia/Sydney
其中左侧时间戳表示当前区域偏移量,右侧时间戳表示转换后的区域偏移量。 日期/时间指示转换即将发生的确切时刻。
从本质上讲, datezone
是一个更好的zdump(8)
。
该工具将strptime(3)
的灵活性引入命令行。 虽然(至少 GNU) date(1)
支持输出格式,但它缺乏从日期域读取任意输入的任何类型的支持,特别是当输入格式事先明确已知并且仅匹配日期/时间时经过考虑的。
使用strptime
工具读取像Mon, May-01/2000
这样的奇怪日期就变成了
strptime -i "%a, %b-%d/%Y" "Mon, May-01/2000" => 2000-05-01
就像你在 C 中所做的那样。
请注意, strptime
实际上使用系统 libc 的 strptime 例程,并使用系统的 strftime 例程进行输出。 因此,输入和输出修饰符在系统之间会有所不同。
对于便携式解析器/打印机组合,请如上所述使用dateconv
。 其输入和输出格式说明符独立于 C 运行时。
排名不分先后,也不保证完整性:
日期表达式:http://www.eskimo.com/~scs/src/#dateexpr
allanfalloon 的 dateutils:https://github.com/alanfalloon/dateutils
是的http://yest.sourceforge.net/
pdd https://github.com/jarun/pdd
使用最适合您目的的一种。 如果您碰巧喜欢我的,请投票:dateutils' openhub 页面