获取自 Linux 上的 Epoch、Bash 以来的当前时间(以秒为单位)
Posted
技术标签:
【中文标题】获取自 Linux 上的 Epoch、Bash 以来的当前时间(以秒为单位)【英文标题】:Get current time in seconds since the Epoch on Linux, Bash 【发布时间】:2010-11-08 17:20:26 【问题描述】:我需要像 date
这样简单的东西,但以 1970 年以来的秒数而不是当前日期、小时、分钟和秒为单位。
date
似乎没有提供该选项。有什么简单的方法吗?
【问题讨论】:
有些版本的 date 有,有些没有。所以它并不总是存在。我运行了 'type -a date' 并使用了不同的版本,并且有效。 FWIW,Ubuntu 只有 /bin/date,@Steef 的回答有效 @TheBonsai 这不是“日期”工具的 POSIX 标准版本的一部分。仅仅因为你的版本有它(可能是 GNU),你不应该假设每个人的实现都有。 【参考方案1】:到目前为止,所有答案都使用外部程序date
。
从 Bash 4.2 开始,printf
有一个新的修饰符 %(dateformat)T
,当它与参数 -1
一起使用时,以dateformat
给出的格式输出当前日期,由strftime(3)
处理(man 3 strftime
获取有关信息格式)。
所以,对于纯 Bash 解决方案:
printf '%(%s)T\n' -1
或者如果您需要将结果存储在变量var
:
printf -v var '%(%s)T' -1
没有外部程序,也没有子shell!
从 Bash 4.3 开始,甚至可以不指定 -1
:
printf -v var '%(%s)T'
(但总是给出参数-1
可能更明智)。
如果您使用-2
作为参数而不是-1
,Bash 将使用shell 的启动时间而不是当前日期。这可以用来计算经过的时间
$ printf -v beg '%(%s)T\n' -2
$ printf -v now '%(%s)T\n' -1
$ echo beg=$beg now=$now elapsed=$((now-beg))
beg=1583949610 now=1583953032 elapsed=3422
【讨论】:
你想使用-2
,以防你有一个运行时间更长的工作(想想一个脚本来控制你的备份)并在最后发送一封邮件“备份开始于$somewhen完成于$now " - 这可以通过 -2
避免在开头存储专用变量来完成。【参考方案2】:
纯 bash 解决方案
由于bash
5.0 (released on 7 Jan 2019) 可以使用内置变量EPOCHSECONDS
。
$ echo $EPOCHSECONDS
1547624774
还有EPOCHREALTIME
,其中包括几分之一秒。
$ echo $EPOCHREALTIME
1547624774.371215
EPOCHREALTIME
可以通过删除小数点转换为微秒 (μs)。这在使用bash
的内置算术(( expression ))
时可能很有趣,它只能处理整数。
$ echo $EPOCHREALTIME/./
1547624774371215
在上面的所有示例中,打印的时间值都是相等的,以提高可读性。实际上,时间值会有所不同,因为每个命令都需要一小段时间来执行。
【讨论】:
对于毫秒分辨率(格式与date +%s%3N
相同)可以使用echo $(( $EPOCHREALTIME/./ / 1000 ))
【参考方案3】:
只是添加。 获取任何给定日期(例如 1973 年 10 月 21 日)的纪元(1970 年 1 月 1 日)以来的秒数。
date -d "Oct 21 1973" +%s
将秒数转换回日期
date --date @120024000
命令date
非常通用。另一个你可以用 date 做的很酷的事情(无耻地从date --help
复制)。
显示美国西海岸下周五上午 9 点的当地时间
date --date='TZ="America/Los_Angeles" 09:00 next Fri'
更好的是,花点时间阅读手册页 http://man7.org/linux/man-pages/man1/date.1.html
【讨论】:
这不是 OP 的问题,但它回答了我的问题,所以 +1 来自我。 可能是date
的版本,或者因为我使用的是zsh
(macOS Catalina),但这对我不起作用。运行$ date -d "Oct 21 1973" +%s
输出usage: date [-jnRu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
@JoshuaPinter 和 macOS 上的其他人,我也有同样的问题。 man date
表明用于解析另一个日期字符串的选项是 macOS 上的 -j
和 -f expectedformat
。 (-d
用于设置夏令时。)
上面的date
命令来自gnu coreutils pacakge。在 mac 上,可以使用 brew 或 macports 安装 gnu coreutils 包。安装后,二进制文件命名为gdate
,以区别于macOS预装的/bin/date
【参考方案4】:
对于大多数 Awk 实现:
awk 'BEGIN srand(); print srand()'
【讨论】:
哇,这太晦涩了 哇,不得不去看看这个。这是一个务实的解决方案,但不一定是好的/便携的。 It seems that implementations of awksrand()
通常以当前日期/时间为种子。第二次调用 srand()
返回之前用作种子的值。
POSIX 兼容,因为这就是 NAWK 的行为方式。很不错。我试图记住这个并追踪了你的帖子。谢谢。【参考方案5】:
使用这个 bash 脚本(我的 ~/bin/epoch
):
#!/bin/bash
# get seconds since epoch
test "x$1" == x && date +%s && exit 0
# or convert epoch seconds to date format (see "man date" for options)
EPOCH="$1"
shift
date -d @"$EPOCH" "$@"
【讨论】:
【参考方案6】:这是 @pellucide 所做的扩展,但适用于 Mac:
确定任何给定日期(例如 1973 年 10 月 21 日)的纪元(1970 年 1 月 1 日)以来的秒数
$ date -j -f "%b %d %Y %T" "Oct 21 1973 00:00:00" "+%s"
120034800
请注意,为了完整起见,我已将时间部分添加到格式中。原因是date
将采用您提供的任何日期部分并将当前 时间添加到提供的值中。例如,如果您在下午 4:19 执行上述命令,没有 '00:00:00' 部分,它将自动添加时间。这样“1973 年 10 月 21 日”将被解析为“1973 年 10 月 21 日 16:19:00”。这可能不是你想要的。
要将您的时间戳转换回日期:
$ date -j -r 120034800
Sun Oct 21 00:00:00 PDT 1973
Apple 的日期实现手册页: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/date.1.html
【讨论】:
明确地说,这是针对 BSD 的date
命令的,而任何建议 date -d
的解决方案都针对 GNU date
。 macOS 中的 BSD 日期 comes from FreeBSD,并与 NetBSD 和 OpenBSD 共享许多选项。这是 与 bash 完全分开的。
MacOS 日期中缺少在 gnu 日期中提到的小数秒的 %N
选项。在 10.14 上,手册页中没有任何格式;它们在 strftime(3)
手册页中,如果您没有安装 Xcode,您将不会拥有该手册页,即使您安装了也可能无法使用 man 命令查看。
通过扩展@ghoti 的评论,这适用于 MacOS。【参考方案7】:
这应该可行:
date +%s
【讨论】:
日期 manpge 应该从%s seconds since 1970-01-01 00:00:00 UTC
更改为 %s seconds since the epoch, 1970-01-01 00:00:00 UTC
因为我错过了它。
对我不起作用。人工日期未显示 %s。我必须有一个非常旧版本的 bash(Solaris 的 3.2.51(1))?
@livefree75 date
未内置于bash
,因此您的bash
版本与您的系统附带的date
实现无关。
如果你想要秒的小数点,到小数点后九位,请使用:date +%s.%N
毫秒使用date +%s%3N
以上是关于获取自 Linux 上的 Epoch、Bash 以来的当前时间(以秒为单位)的主要内容,如果未能解决你的问题,请参考以下文章
获取自 UTC 日期的 EPOCH 以来返回错误结果的毫秒? [复制]
在 Python 3.6.9 中以纳秒为单位获取 Epoch 时间戳