簡體   English   中英

在 Bash 中將日期時間字符串轉換為紀元

[英]Convert date time string to epoch in Bash

日期時間字符串采用以下格式:06/12/2012 07:21:22。 如何將其轉換為 UNIX 時間戳或紀元?

您正在尋找的是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 ,而不是英國、歐盟或任何其他格式。

對於 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"

很多這些答案都過於復雜,而且還缺少如何使用變量。 這是在標准 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
}

只要確定你想使用什么時區。

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"

使用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

這必須輸出當前的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進行轉換,而是只運行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

樣本:

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

或者使用我的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

注意:GitHub 上,函數和測試是分開的文件。 我的網站的測試,如果該腳本不來源是簡單地運行。

# Exit here if script is sourced
[ "$0" = "$BASH_SOURCE" ] || { true;return 0;}
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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM