【问题标题】:Convert date time string to epoch in Bash在 Bash 中将日期时间字符串转换为纪元
【发布时间】:2012-06-14 23:57:28
【问题描述】:

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

【问题讨论】:

    标签: bash shell date


    【解决方案1】:

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

    请参阅date 的其他版本的相应手册页。

    注意:bash --date-d 选项需要美国或 ISO8601 格式的日期,即 mm/dd/yyyyyyyy-mm-dd,而不是英国、欧盟或任何其他格式。

    【讨论】:

    • 我在 Mac OSX 10.8.2 上运行时得到“日期:非法选项 --”
    • 对于像我这样的菜鸟,+"%s" 代表输出格式,%s 是自 1970 年以来以秒为单位的时间格式
    • 注意:如果您想指定另一个时区(如 UTC)的时间,请在末尾添加 -HHMM 或 +HHMM。所以date --date='06/12/2012 07:21:22 -0000' +"%s" 将 UTC 日期转换为 unix 时间戳
    • 对于 GNU 日期,如果您希望使用 UTC,请注意格式为 yyyy-mm-dd hh:mm:ss查看gnu.org/software/coreutils/manual/html_node/…gdate --date='2019-06-18 00:02:00 +0000' +%s
    • 不能在 Mac 上工作...我想知道是否有一种方法可以同时在 Mac 和 Linux 上工作
    【解决方案2】:

    对于 Linux,运行以下命令:

    date -d '06/12/2012 07:21:22' +"%s"
    

    对于 macOS,运行以下命令:

    date -j -u -f "%a %b %d %T %Z %Y" "Tue Sep 28 19:35:15 EDT 2010" "+%s"
    

    【讨论】:

    • 在 OSX 上,时间戳随当前时间增加。我目前对此没有任何解释......
    • 更新:那是因为它调整了我的本地时间的时间戳,我猜......添加一个 -u 标志应该可以解决这个问题。
    • @AbdulRehmanJanjua -u 标志应该出现在 -f 标志之前,否则 shell 会将其解释为格式字符串。所以,应该是:date -j -u -f "%a..."
    • 在 macOS 终端中完全粘贴失败。
    • date -jf "%Y-%m-%d %H:%M:%S" "2018-01-08 14:45:00" +%s
    【解决方案3】:

    很多这些答案都过于复杂,而且还缺少如何使用变量。这就是您在标准 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"
    

    结果:

    RESULTS:
    original = Apr 28 07:50:01
    epoch conv = 1524916201 
    epoch to human readable time stamp = 20180428_075001
    

    或者作为一个函数:

    # -- 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
    }
    

    【讨论】:

      【解决方案4】:

      只要确定你想使用哪个时区。

      datetime="06/12/2012 07:21:22"
      

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

      date -d "$datetime" +"%s" #depends on local timezone, my output = "1339456882"
      

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

      date -u -d "$datetime" +"%s" #general output = "1339485682"
      

      【讨论】:

      • 如果我的日期格式是“YYYYmmdd”怎么办?前任。 20200827
      • 您也可以使用它。 date 正确格式化此输入。
      【解决方案5】:

      在bash中将日期时间字符串转换为epoch的有效方法

      避免无用的重复分叉,以使翻译更快...

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

      简介

      常用语法:

      epochDate=$(date -d "$InputDate" +%s)
      

      工作正常,但如果重复运行会变得沉重!

      在这篇文章中,你会发现

      • 快速演示,在此之后,
      • 一些解释
      • 一个函数可用于许多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
      

      这必须输出当前的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
      

      和:

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

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

      您可以检查echo $ans,将"now" 替换为"2019-25-12 20:10:00" 等等...

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

      exec 5>&- ; exec 6<&-
      

      原帖(详解)

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

      date -f - +%s <<eof
      Apr 17  2014
      May 21  2012
      Mar  8 00:07
      Feb 11 00:09
      eof
      1397685600
      1337551200
      1520464020
      1518304140
      

      示例:

      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" )
      

      那么现在看看:

      declare -p start1 start2 dirchg userdate
      

      (可能会这样回答:

      declare -- start1="1518549549"
      declare -- start2="1520183716"
      declare -- dirchg="1520601919"
      declare -- userdate="1397685600"
      

      这是一次执行!

      使用长时间运行子进程

      我们只需要一个fifo

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

      (注意:由于进程正在运行并且所有描述符都已打开,我们可以安全地删除 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
      

      我们可以建立一个小功能:

      mydate() {
          local var=$1;
          shift;
          echo >&7 $@
          read -u 8 $var
      }
      
      mydate start1 $(LANG=C ps ho lstart 1)
      echo $start1
      

      或者使用mynewConnector函数

      函数用于连接 MySQL/MariaDBPostgreSQLSQLite...

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

      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
      

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

      # Exit here if script is sourced
      [ "$0" = "$BASH_SOURCE" ] || { true;return 0;}
      

      【讨论】:

        【解决方案6】:
        get_curr_date () {
            # get unix time
            DATE=$(date +%s)
            echo "DATE_CURR : "$DATE
        }
        
        conv_utime_hread () {
            # convert unix time to human readable format
            DATE_HREAD=$(date -d @$DATE +%Y%m%d_%H%M%S)
            echo "DATE_HREAD          : "$DATE_HREAD
        }
        

        【讨论】:

        • 欢迎来到 Stack Overflow。考虑在您的代码之外添加解释。
        猜你喜欢
        • 2012-04-03
        • 2018-02-18
        • 2012-11-22
        • 2014-11-18
        • 1970-01-01
        • 2017-11-10
        • 1970-01-01
        • 2023-03-18
        • 1970-01-01
        相关资源
        最近更新 更多