我需要一个shell命令或脚本,将Unix时间戳转换为日期。输入可以来自第一个参数,也可以来自stdin,允许以下使用模式:

ts2date 1267619929

and

echo 1267619929 | ts2date

这两个命令都应该输出“Wed Mar 3 13:38:49 2010”。


当前回答

我喜欢以前的特殊情况下的解决方案:printf '%(%c)T\n' $timestamp(如果你有Bash>=4.2), date -d @$timestamp(如果你有GNU Coreutils >= 5.3.0), date -r $timestamp(如果你是BSD/MacOS),但我需要一些更可移植的东西,我选择了jq,我到处都有JSON的帮助:

jq 'todate' <<< $timestamp

可以在函数中使用,以获得所需的效果:

ts2date() { [[ -n "$1" ]] && { jq 'todate' <<< $1 ; true;} || jq 'todate' ; }

其他回答

我使用这个跨平台的一行代码:

date -d @1267619929 2>/dev/null || date -r 1267619929

它应该可以在macOS和流行的Linux发行版的现代版本中运行。

一些例子:

$ date
Tue Mar 22 16:47:06 CST 2016

$ date -d "Tue Mar 22 16:47:06 CST 2016" "+%s"
1458636426

$ date +%s
1458636453

$ date -d @1458636426
Tue Mar 22 16:47:06 CST 2016

$ date --date='@1458636426'
Tue Mar 22 16:47:06 CST 2016


在GNU Coreutils >= 5.3.0的系统上,例如Linux,您可以使用:

date -d @1267619929

例如,你可以使用GNU日期,

$ sec=1267619929
$ date -d "UTC 1970-01-01 $sec secs"

or

$ date -ud @1267619929

虽然不是纯bash,但下面的脚本将使用perl将字符串中长度为13的时间戳转换为本地时区中的等效日期

timestamp_to_date.sh

#!/usr/bin/env bash
IT=$(cat /dev/stdin)
re='(.*)([0-9]{13})(.*)'
while [[ $IT =~ $re ]]; do
  TIMESTAMP=${BASH_REMATCH[2]}
  AS_DATE=$(echo "$TIMESTAMP" | perl -pe 's/([\d]{10})([\d]{3})/localtime $1/eg;')
  IT="${IT/$TIMESTAMP/$AS_DATE}"    
done
echo "$IT"

输入

{"timestamp":"1573121629939","level":"DEBUG","thread":"http-nio-15372-exec-3","logger":"org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor"}

输出

$ cat input | timestamp_to_date.sh

{"timestamp":"Thu Nov  7 06:13:49 2019","level":"DEBUG","thread":"http-nio-15372-exec-3","logger":"org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor"}