将 Unix 时间戳转换为日期字符串

发布于 2024-09-10 02:03:38 字数 143 浏览 11 评论 0原文

有没有一种快速、单行的方法可以从 Unix 命令行将 Unix 时间戳转换为日期?

date 可能会起作用,但指定每个元素(月、日、年、小时等)相当尴尬,而且我不知道如何让它正常工作。似乎可能有一种更简单的方法——我错过了什么吗?

Is there a quick, one-liner way to convert a Unix timestamp to a date from the Unix command line?

date might work, except it's rather awkward to specify each element (month, day, year, hour, etc.), and I can't figure out how to get it to work properly. It seems like there might be an easier way — am I missing something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

永不分离 2024-09-17 02:03:39
awk 'BEGIN { print strftime("%c", 1271603087); }'
awk 'BEGIN { print strftime("%c", 1271603087); }'
痴骨ら 2024-09-17 02:03:39

将以下内容放入 ~/.bashrc :

function unixts() { date -d "@$1"; }

示例用法:

$ unixts 1551276383

Wed Feb 27 14:06:23 GMT 2019

Put the following in your ~/.bashrc :

function unixts() { date -d "@$1"; }

Example usage:

$ unixts 1551276383

Wed Feb 27 14:06:23 GMT 2019
白云不回头 2024-09-17 02:03:39

Python:

python -c "from datetime import datetime; print(datetime.fromtimestamp($TIMESTAMP))"

Python:

python -c "from datetime import datetime; print(datetime.fromtimestamp($TIMESTAMP))"
请帮我爱他 2024-09-17 02:03:39

3 备注:

.1 关于

因为这个问题被标记为 且此处没有答案地址 printf bashism

语法:printf '%(fmt)T' $UNIXEPOCH

在 bash 下,从 V4.2 开始(2011 年 2 月),printf 内置有一个 %(fmt)T 说明符,允许时间值使用类似 strftime 的格式。

TZ=UTC LANG=C printf '%(%A %d %b %Y, %T %Z)T\n' 12345678
Saturday 23 May 1970, 21:21:18 UTC

不带参数或使用 -1 作为参数使用,这将打印当前时间:

printf '%(%b %d, %T)T\n' 
Aug 03, 08:42:28

作为 printf 对于命令行中存在的尽可能多的参数重复格式序列

$ TZ=UTC LANG=C printf '%(%A %d %b %Y, %T %Z)T\n' -1 123456789 $EPOCHSECONDS
Sunday 20 Nov 2022, 13:04:42 UTC
Thursday 29 Nov 1973, 21:33:09 UTC
Sunday 20 Nov 2022, 13:04:42 UTC

如果没有参数且没有 fmt 字符串,printf '%()T' 将打印当前时间:

printf '%()T\n'
12:34:56

echo $(( $(TZ=UTC printf "%()T" | sed 's/:/* 3600 +/;s/:/* 60 +/') -
         $(printf "%(%s)T") % 86400 ))
0

.2 $EPOCHSECONDS< /code> 和 $EPOCHREALTIME 整型变量

从 V5.0 开始,bash 环境提供了两个整型变量:$EPOCHSECONDS 扩展为自 Unix 纪元以来的秒数和 >$EPOCHREALTIME 扩展为自 Unix 纪元以来的时间(以微秒为单位)。

myvar1=$(LANG=C date -d 'now -1 day' +%c)
LANG=C printf -v myvar2 '%(%c)T' $(( EPOCHSECONDS - 86400 ))
[[ $myvar1 == "$myvar2" ]] || echo "Something's wrong: '$myvar1' != '$myvar2'!"

除了非常小的时间间隔,其中时间在设置 $myvar1$myvar2,此代码不会产生任何输出,因为 $myvar1 应包含与 $myvar2 完全相同的字符串。

declare -p myvar{1,2}
declare -- myvar1="Tue Aug  2 11:11:35 2022"
declare -- myvar2="Tue Aug  2 11:11:35 2022"

由于 printf 是一个内置,因此没有fork 用于从 UNIXTIME 转换分配字符串变量。

唯一的区别是资源占用,然后是执行时间。

有关 $EPOCHREALTIME 的更多信息和建议,请参阅如何使用 bash 内置函数打印当前时间(以微秒为单位)

.3 关于许多条目的 GNU date

选项 -f

使用 GNU date,如果您打算格式化一个大的一堆unixtimestamp,您可以使用date命令作为过滤器。

首先,您必须在每个时间戳之前添加 At (@),然后添加 date -f< /code> 可以在一次操作中处理每个输入行:

sed 's/^/@/' < inputfile |
    date -f - +'%A %d %b %Y, %T %Z'

示例:

seq 123456789 $(((EPOCHSECONDS-123456789)/4)) $EPOCHSECONDS |
    sed 's/^/@/' |
    LANG=C TZ=GMT date -f - +'%A %d %b %Y, %T %Z'

应该生成类似以下内容的内容:

Thursday 29 Nov 1973, 21:33:09 GMT
Thursday 30 Jan 1986, 11:53:49 GMT
Thursday 02 Apr 1998, 02:14:29 GMT
Wednesday 02 Jun 2010, 16:35:09 GMT
Wednesday 03 Aug 2022, 06:55:49 GMT

.4 转换流式日志文件

这可能会被命名为

将流式 Unix 时间戳实时转换为日期字符串

使用来自远程服务器的 tail -f squid/access.log 进行示例。

squid 日志如下所示:

1659526597.212 240128 192.168.0.184 TCP_TUNNEL/200 3383 连接 safebrowsing.googleapis.com:443 - HIER_DIRECT/172.217.168.74 -
1659526614.078 753 192.168.0.91 TCP_TUNNEL/200 3800 连接 shavar.services.mozilla.com:443 - HIER_DIRECT/44.236.110.253 -

为了能够远程跟踪一些squid代理,我可以使用这个:

exec {fd}<> <(:) # This will open unnamed fifo.

然后

ssh root@proxyserver tail -f /var/log/squid/access.log |
    tee >(
        exec sed -ue 's/^\([0-9]\+\)\..*/@\1/'|
            stdbuf -i0 -o0 date -f - +%c >/dev/fd/$fd
     ) |
    sed -ue 's/^[0-9]\+\././'|
        paste -d '' /dev/fd/$fd -

这将输出无缓冲,如下所示:

Wed Aug  3 13:36:37 2022.212 240128 192.168.0.184 TCP_TUNNEL/200 3383 CONNECT safebrowsing.googleapis.com:443 - HIER_DIRECT/172.217.168.74 -
Wed Aug  3 13:36:54 2022.078    753 192.168.0.91 TCP_TUNNEL/200 3800 CONNECT shavar.services.mozilla.com:443 - HIER_DIRECT/44.236.110.253 -

可以通过Ctrl停止+C,然后重新运行多次,直到通过以下方式关闭 $fd 未命名 fifo:

exec {fd}<&-

3 remarks:

.1 about

As this question is tagged and no answer here address printf bashism:

Syntax: printf '%(fmt)T' $UNIXEPOCH

Under bash, from V4.2, (Feb 2011), The printf builtin has a %(fmt)T specifier, which allows time values to use strftime-like formatting.

TZ=UTC LANG=C printf '%(%A %d %b %Y, %T %Z)T\n' 12345678
Saturday 23 May 1970, 21:21:18 UTC

Used without argument or with -1 as argument, this will print current time:

printf '%(%b %d, %T)T\n' 
Aug 03, 08:42:28

As printf repeat format sequenc for as many argument present in command line:

$ TZ=UTC LANG=C printf '%(%A %d %b %Y, %T %Z)T\n' -1 123456789 $EPOCHSECONDS
Sunday 20 Nov 2022, 13:04:42 UTC
Thursday 29 Nov 1973, 21:33:09 UTC
Sunday 20 Nov 2022, 13:04:42 UTC

Without argument and without fmt string, printf '%()T' will print current time:

printf '%()T\n'
12:34:56

echo $(( $(TZ=UTC printf "%()T" | sed 's/:/* 3600 +/;s/:/* 60 +/') -
         $(printf "%(%s)T") % 86400 ))
0

.2 The $EPOCHSECONDS and $EPOCHREALTIME integer variables

From V5.0, bash's environment present two integer variables: $EPOCHSECONDS which expands to the time in seconds since the Unix epoch and $EPOCHREALTIME which expands to the time in seconds since the Unix epoch with microsecond granularity..

myvar1=$(LANG=C date -d 'now -1 day' +%c)
LANG=C printf -v myvar2 '%(%c)T' $(( EPOCHSECONDS - 86400 ))
[[ $myvar1 == "$myvar2" ]] || echo "Something's wrong: '$myvar1' != '$myvar2'!"

Except in a very small time laps, where time rounded to second increment by one second between setting $myvar1 and $myvar2, this code won't produce any output as $myvar1 should contain exactly same string than $myvar2.

declare -p myvar{1,2}
declare -- myvar1="Tue Aug  2 11:11:35 2022"
declare -- myvar2="Tue Aug  2 11:11:35 2022"

As printf is a builtin, there is no fork for assigning string variable from UNIXTIME conversion.

The only difference would be resource footprint, then execution time.

Further informations and recommendations about $EPOCHREALTIME, see How to print current time in microseconds using bash builtin

.3 About GNU date

option -f for many entries

Using GNU date, if you plan to format a big bunch of unixtimestamp, you could use date command as a filter.

First you have to add a At (@) before each timestamp, then date -f could process each input lines in one operation:

sed 's/^/@/' < inputfile |
    date -f - +'%A %d %b %Y, %T %Z'

Sample:

seq 123456789 $(((EPOCHSECONDS-123456789)/4)) $EPOCHSECONDS |
    sed 's/^/@/' |
    LANG=C TZ=GMT date -f - +'%A %d %b %Y, %T %Z'

Should produce something like:

Thursday 29 Nov 1973, 21:33:09 GMT
Thursday 30 Jan 1986, 11:53:49 GMT
Thursday 02 Apr 1998, 02:14:29 GMT
Wednesday 02 Jun 2010, 16:35:09 GMT
Wednesday 03 Aug 2022, 06:55:49 GMT

.4 Converting streamed logfile

This could be titled

Convert streamed Unix timestamp to date strings in real time.

Sample using tail -f squid/access.log, from a remote server.

squid logs look like:

1659526597.212 240128 192.168.0.184 TCP_TUNNEL/200 3383 CONNECT safebrowsing.googleapis.com:443 - HIER_DIRECT/172.217.168.74 -
1659526614.078    753 192.168.0.91 TCP_TUNNEL/200 3800 CONNECT shavar.services.mozilla.com:443 - HIER_DIRECT/44.236.110.253 -

To be able to remotely follow some squid proxy I could use this:

exec {fd}<> <(:) # This will open unnamed fifo.

Then

ssh root@proxyserver tail -f /var/log/squid/access.log |
    tee >(
        exec sed -ue 's/^\([0-9]\+\)\..*/@\1/'|
            stdbuf -i0 -o0 date -f - +%c >/dev/fd/$fd
     ) |
    sed -ue 's/^[0-9]\+\././'|
        paste -d '' /dev/fd/$fd -

This will output without buffering, something like this:

Wed Aug  3 13:36:37 2022.212 240128 192.168.0.184 TCP_TUNNEL/200 3383 CONNECT safebrowsing.googleapis.com:443 - HIER_DIRECT/172.217.168.74 -
Wed Aug  3 13:36:54 2022.078    753 192.168.0.91 TCP_TUNNEL/200 3800 CONNECT shavar.services.mozilla.com:443 - HIER_DIRECT/44.236.110.253 -

Could be stopped by Ctrl+C, then re-run many time, until you close $fd unnamed fifo by:

exec {fd}<&-
摘星┃星的人 2024-09-17 02:03:38

带有 date GNU coreutils 你可以这样做:(

date -d "@$TIMESTAMP"
# date -d @0
Wed Dec 31 19:00:00 EST 1969

来自:BASH:将 Unix 时间戳转换为日期)

在 OS X 上,使用 date -r

date -r "$TIMESTAMP"

或者,使用 strftime()。它不能直接从 shell 获取,但您可以通过 gawk 访问它。 %c 说明符以区域设置相关的方式显示时间戳。

echo "$TIMESTAMP" | gawk '{print strftime("%c", $0)}'
# echo 0 | gawk '{print strftime("%c", $0)}'
Wed 31 Dec 1969 07:00:00 PM EST

With date from GNU coreutils you can do:

date -d "@$TIMESTAMP"
# date -d @0
Wed Dec 31 19:00:00 EST 1969

(From: BASH: Convert Unix Timestamp to a Date)

On OS X, use date -r.

date -r "$TIMESTAMP"

Alternatively, use strftime(). It's not available directly from the shell, but you can access it via gawk. The %c specifier displays the timestamp in a locale-dependent manner.

echo "$TIMESTAMP" | gawk '{print strftime("%c", $0)}'
# echo 0 | gawk '{print strftime("%c", $0)}'
Wed 31 Dec 1969 07:00:00 PM EST
枯叶蝶 2024-09-17 02:03:38

日期 -d @1278999698 +'%Y-%m-%d %H:%M:%S'
其中@后面的数字是秒数

date -d @1278999698 +'%Y-%m-%d %H:%M:%S'
Where the number behind @ is the number in seconds

め可乐爱微笑 2024-09-17 02:03:38

此解决方案适用于不支持 date -d @ 的 date 版本。它不需要 AWK 或其他命令。 Unix 时间戳是自 1970 年 1 月 1 日以来的秒数(UTC),因此在输入中指定 UTC 非常重要。

date -d '1970-01-01 1357004952 sec UTC'
Mon Dec 31 17:49:12 PST 2012

如果您使用的是 Mac,则使用:

date -r 1357004952

获取纪元的命令:

date +%s
1357004952

感谢 Anton:BASH:将 Unix 时间戳转换为日期

This solution works with versions of date which do not support date -d @. It does not require AWK or other commands. A Unix timestamp is the number of seconds since Jan 1, 1970, UTC so it is important to specify UTC in the input.

date -d '1970-01-01 1357004952 sec UTC'
Mon Dec 31 17:49:12 PST 2012

If you are on a Mac, then use:

date -r 1357004952

Command for getting epoch:

date +%s
1357004952

Credit goes to Anton: BASH: Convert Unix Timestamp to a Date

听你说爱我 2024-09-17 02:03:38

正如 @TomMcKenzie 在对另一个答案的评论中所说,对于自 Unix 纪元以来以秒为单位的时间,date -r 123456789 可以说是一个更常见(即更广泛实现)的简单解决方案,但不幸的是没有通用的有保证的便携式解决方案。

许多类型的系统上的 -d 选项的含义与 GNU Date 的 --date 扩展完全不同。遗憾的是,GNU Date 的解释 -r 与这些其他实现的方式不同。因此不幸的是,您必须知道您正在使用哪个版本的 date,并且许多旧的 Unix date 命令不支持这两个选项。

更糟糕的是,POSIX date 既不识别 -d 也不识别 -r 并且在任何命令中根本不提供标准方法(据我所知)从命令行格式化 Unix 时间(因为 POSIX Awk 也缺少 strftime())。 (您不能使用 touch -tls 因为前者不接受自 Unix Epoch 以来以秒为单位的时间。)

请注意,The One True Awk 可以直接使用来自 Brian Kernighan 的现在确实内置了 strftime() 函数以及 systime() 函数,用于返回自 Unix 纪元以来的当前时间(以秒为单位),因此也许 Awk 解决方案是最可移植的。

As @TomMcKenzie says in a comment to another answer, date -r 123456789 is arguably a more common (i.e. more widely implemented) simple solution for times given as seconds since the Unix Epoch, but unfortunately there's no universal guaranteed portable solution.

The -d option on many types of systems means something entirely different than GNU Date's --date extension. Sadly GNU Date doesn't interpret -r the same as these other implementations. So unfortunately you have to know which version of date you're using, and many older Unix date commands don't support either option.

Even worse, POSIX date recognizes neither -d nor -r and provides no standard way in any command at all (that I know of) to format a Unix time from the command line (since POSIX Awk also lacks strftime()). (You can't use touch -t and ls because the former does not accept a time given as seconds since the Unix Epoch.)

Note though The One True Awk available direct from Brian Kernighan does now have the strftime() function built-in as well as a systime() function to return the current time in seconds since the Unix Epoch), so perhaps the Awk solution is the most portable.

岁月染过的梦 2024-09-17 02:03:38

对上面 dabest1 的答案稍作修正。将时区指定为 UTC,而不是 GMT:

$ date -d '1970-01-01 1416275583 sec GMT'
Tue Nov 18 00:53:03 GMT 2014
$ date -d '1970-01-01 1416275583 sec UTC'
Tue Nov 18 01:53:03 GMT 2014

第二个是正确的。我认为原因是英国从1968年到1971年一直实行夏令时。

Slight correction to dabest1's answer above. Specify the timezone as UTC, not GMT:

$ date -d '1970-01-01 1416275583 sec GMT'
Tue Nov 18 00:53:03 GMT 2014
$ date -d '1970-01-01 1416275583 sec UTC'
Tue Nov 18 01:53:03 GMT 2014

The second one is correct. I think the reason is that in the UK, daylight saving was in force continually from 1968 to 1971.

贱贱哒 2024-09-17 02:03:38

如果您发现这种表示法很尴尬,也许 -R - 选项会有所帮助。它以 RFC 2822 格式输出日期。因此,您不需要所有这些标识符:date -d @1278999698 -R。另一种可能性是在您的语言环境中输出以秒为单位的日期:date -d @1278999698 +%c。应该很容易记住。 :-)

If you find the notation awkward, maybe the -R-option does help. It outpouts the date in RFC 2822 format. So you won't need all those identifiers: date -d @1278999698 -R. Another possibility is to output the date in seconds in your locale: date -d @1278999698 +%c. Should be easy to remember. :-)

恬淡成诗 2024-09-17 02:03:38

这里的其他例子很难记住。最简单的说:

date -r 1305712800

Other examples here are difficult to remember. At its simplest:

date -r 1305712800
撞了怀 2024-09-17 02:03:38

标准 Perl 解决方案是:(

echo $TIMESTAMP | perl -nE 'say scalar gmtime $_'

或当地时间,如果愿意的话)

The standard Perl solution is:

echo $TIMESTAMP | perl -nE 'say scalar gmtime $_'

(or localtime, if preferred)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文