在Bash中将日期时间字符串转换为纪元

Edw*_* D. 74 bash shell date

日期时间字符串采用以下格式:06/12/2012 07:21:22.如何将其转换为UNIX时间戳或纪元?

Dan*_*zar 76

你在寻找什么date --date='06/12/2012 07:21:22' +"%s".请记住,这是假定你使用GNU的coreutils,既--date%s格式字符串是GNU扩展.POSIX没有指定其中任何一个,因此即使在符合POSIX的系统上也没有可移植的方式进行此类转换.

有关其他版本的信息,请参阅相应的手册页date.

注意:bash --date-doption期望日期为美国或ISO8601格式,即mm/dd/yyyyyyyy-mm-dd不是英国,欧盟或任何其他格式.

  • 当我在Mac OSX 10.8.2上运行时,我得到'日期:非法选项 - ' (7认同)
  • 注意:如果您想指定另一个时区(如 UTC)的时间,请在末尾添加 -HHMM 或 +HHMM。所以`date --date='06/12/2012 07:21:22 -0000' +"%s"` 将UTC日期转换为unix时间戳 (4认同)
  • 像我这样的新手`+"%s"`代表输出格式,'%s`是自1970年以来以秒为单位的时间格式 (3认同)
  • 对于 GNU 日期,如果您想使用 UTC 请注意格式是`yyyy-mm-dd hh:mm:ss`看看https://www.gnu.org/software/coreutils/manual/html_node/Examples -of-date.html : `gdate --date='2019-06-18 00:02:00 +0000' +%s` (2认同)

Abd*_*jua 41

对于Linux运行此命令

date -d '06/12/2012 07:21:22' +"%s"
Run Code Online (Sandbox Code Playgroud)

对于mac OSX,运行此命令

date -j -u -f "%a %b %d %T %Z %Y" "Tue Sep 28 19:35:15 EDT 2010" "+%s"
Run Code Online (Sandbox Code Playgroud)

  • `date -jf“%Y-%m-%d%H:%M:%S”“ 2018-01-08 14:45:00” +%s` (4认同)
  • 更新:那是因为它调整了我的本地时间的时间戳我猜...添加`-u`标志应该解决这个问题. (3认同)
  • 将其精确粘贴到macOS终端失败。 (2认同)

Jso*_*owa 6

只要确定你想使用什么时区。

datetime="06/12/2012 07:21:22"
Run Code Online (Sandbox Code Playgroud)

最流行的使用需要机器时区。

date -d "$datetime" +"%s" #depends on local timezone, my output = "1339456882"
Run Code Online (Sandbox Code Playgroud)

但是,如果您故意想要传递 UTC 日期时间并且想要正确的时区,则需要添加-u标志。否则,您将其从本地时区转换。

date -u -d "$datetime" +"%s" #general output = "1339485682"
Run Code Online (Sandbox Code Playgroud)


F. *_*uri 5

date用作后台专用进程的高效解决方案

避免无用的重复分叉,以便更快地进行此翻译......

我们可以date -f - +%s作为后台进程运行,而不是为每个翻译运行 1 个 fork ...

介绍

在这篇文章中,你会发现

  • 一个快速演示,在此之后,
  • 一些解释
  • 可用于许多Un*x工具 ( , , ...)的函数bcrot13sed

快速演示

fifo=$HOME/.fifoDate-$$
mkfifo $fifo
exec 5> >(exec stdbuf -o0 date -f - +%s >$fifo 2>&1)
echo now 1>&5
exec 6< $fifo
rm $fifo
read -t 1 -u 6 now
echo $now
Run Code Online (Sandbox Code Playgroud)

这必须输出当前的UNIXTIME。从那里,你可以比较

time for i in {1..5000};do echo >&5 "now" ; read -t 1 -u6 ans;done
real    0m0.298s
user    0m0.132s
sys     0m0.096s
Run Code Online (Sandbox Code Playgroud)

和:

time for i in {1..5000};do ans=$(date +%s -d "now");done 
real    0m6.826s
user    0m0.256s
sys     0m1.364s
Run Code Online (Sandbox Code Playgroud)

从超过6秒到不到半秒!!(在我的主机上)。

你可以检查echo $ans,更换"now""2019-25-12 20:10:00"等等...

或者,一旦日期子流程的要求结束,您可以:

exec 5>&- ; exec 6<&-
Run Code Online (Sandbox Code Playgroud)

原帖(详细解释)

不要按日期运行 1 个fork进行转换,date只需运行1 次并使用相同的过程完成所有转换(这可能会变得更快)!:

date -f - +%s <<eof
Apr 17  2014
May 21  2012
Mar  8 00:07
Feb 11 00:09
eof
1397685600
1337551200
1520464020
1518304140
Run Code Online (Sandbox Code Playgroud)

样本:

start1=$(LANG=C ps ho lstart 1)
start2=$(LANG=C ps ho lstart $$)
dirchg=$(LANG=C date -r .)
read -p "A date: " userdate
{ read start1 ; read start2 ; read dirchg ; read userdate ;} < <(
   date -f - +%s <<<"$start1"$'\n'"$start2"$'\n'"$dirchg"$'\n'"$userdate" )
Run Code Online (Sandbox Code Playgroud)

那么现在来看看:

declare -p start1 start2 dirchg userdate
Run Code Online (Sandbox Code Playgroud)

(可能会回答类似:

declare -- start1="1518549549"
declare -- start2="1520183716"
declare -- dirchg="1520601919"
declare -- userdate="1397685600"
Run Code Online (Sandbox Code Playgroud)

这是一次执行完成的!

使用长时间运行的子进程

我们只需要一个fifo

mkfifo /tmp/myDateFifo
exec 7> >(exec stdbuf -o0 /bin/date -f - +%s >/tmp/myDateFifo)
exec 8</tmp/myDateFifo
rm /tmp/myDateFifo
Run Code Online (Sandbox Code Playgroud)

(注意:当进程正在运行并且所有描述符都打开时,我们可以安全地删除 fifo 的文件系统条目。)

那么现在:

LANG=C ps ho lstart 1 $$ >&7
read -u 8 start1
read -u 8 start2
LANG=C date -r . >&7
read -u 8 dirchg

read -p "Some date: " userdate
echo >&7 $userdate
read -u 8 userdate
Run Code Online (Sandbox Code Playgroud)

我们可以构建一个小函数:

mydate() {
    local var=$1;
    shift;
    echo >&7 $@
    read -u 8 $var
}

mydate start1 $(LANG=C ps ho lstart 1)
echo $start1
Run Code Online (Sandbox Code Playgroud)

或者使用我的 newConnector功能

随着功能连接 MySQL/MariaDBPostgreSQLSQLite...

您可以在GitHub或我的网站上找到不同版本的它们:下载显示

wget https://raw.githubusercontent.com/F-Hauri/Connector-bash/master/shell_connector.bash

. shell_connector.bash 
newConnector /bin/date '-f - +%s' @0 0

myDate "2018-1-1 12:00" test
echo $test
1514804400
Run Code Online (Sandbox Code Playgroud)

注意:GitHub 上,函数和测试是分开的文件。在我的网站的测试,如果该脚本不只是运行的来源

# Exit here if script is sourced
[ "$0" = "$BASH_SOURCE" ] || { true;return 0;}
Run Code Online (Sandbox Code Playgroud)


Mik*_*e Q 5

这些答案很多都过于复杂,而且也缺少如何使用变量。这是您在标准Linux系统上更简单的方法(如前所述,必须为Mac用户调整date命令):

示例脚本:

#!/bin/bash
orig="Apr 28 07:50:01"
epoch=$(date -d "${orig}" +"%s")
epoch_to_date=$(date -d @$epoch +%Y%m%d_%H%M%S)    

echo "RESULTS:"
echo "original = $orig"
echo "epoch conv = $epoch"
echo "epoch to human readable time stamp = $epoch_to_date"
Run Code Online (Sandbox Code Playgroud)

结果是 :

RESULTS:
original = Apr 28 07:50:01
epoch conv = 1524916201 
epoch to human readable time stamp = 20180428_075001
Run Code Online (Sandbox Code Playgroud)

或作为功能:

# -- Converts from human to epoch or epoch to human, specifically "Apr 28 07:50:01" human.
#    typeset now=$(date +"%s")
#    typeset now_human_date=$(convert_cron_time "human" "$now")

function convert_cron_time() {
    case "${1,,}" in
        epoch)
            # human to epoch (eg. "Apr 28 07:50:01" to 1524916201)
            echo $(date -d "${2}" +"%s")
            ;;
        human)
            # epoch to human (eg. 1524916201 to "Apr 28 07:50:01")
            echo $(date -d "@${2}" +"%b %d %H:%M:%S")
            ;;
    esac
}
Run Code Online (Sandbox Code Playgroud)