Bashで日時文字列をエポックに変換する


92

日付と時刻の文字列は、06/12/2012 07:21:22の形式です。どうすればUNIXタイムスタンプまたはエポックに変換できますか?

回答:


94

あなたが探しているのは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、ない英国、EU、またはその他の形式では。


9
Mac OSX 10.8.2で実行すると「日付:無効なオプション-」が表示されます
ベンクレイトン

6
私のような初心者にとって+"%s"、出力形式を意味し%s、1970年からの秒単位の時間形式です
razz

2
注:別のタイムゾーン(UTCなど)で時刻を指定する場合は、末尾に-HHMMまたは+ HHMMを追加します。したがって、date --date='06/12/2012 07:21:22 -0000' +"%s"UTC日付をUNIXタイムスタンプに変換します
グレッグブレイ

GNU日付の場合、UTCを使用する場合、形式はgnu.org/software/coreutils/manual/html_node/…にyyyy-mm-dd hh:mm:ssあることに注意してください。gdate --date='2019-06-18 00:02:00 +0000' +%s
アッシュートッシュジンダル

Macでは動作しません... MacとLinuxの両方で動作する方法はあるのでしょうか
非極性

47

Linuxの場合このコマンドを実行します

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

Mac OSXの場合、このコマンドを実行します

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

1
OSXでは、タイムスタンプは現在の時間とともに何らかの形で増加します。現在のところ、その説明はありません...
polym

3
更新:それは私が推測するローカルタイムのタイムスタンプを調整するためでした... -uフラグを追加することで修正されるはずです。
polym 2015

@AbdulRehmanJanjua -uフラグが来る必要があります前に-f、それフォーマット文字列フラグ、または他のシェル解釈。だから、それは次のようになります。date -j -u -f "%a..."

4
macOS端末でそれを正確に貼り付けると失敗します。
zneak 2017

6
date -jf "%Y-%m-%d %H:%M:%S" "2018-01-08 14:45:00" +%s
daviestar

10

これらの回答の多くは非常に複雑で、変数の使用方法もありません。これは、標準の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
}

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

5
Stack Overflowへようこそ。コードに加えて説明を追加することを検討してください。
Olivier De Meulder 2015年

2

バックグラウンド専用プロセスdateとして使用する効率的なソリューション

この種の翻訳をより速くするために...

はじめに

この投稿では、

  • クイックデモこの次、
  • いくつかの説明
  • 関数の多くに使用可能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秒以上から0.5秒未満まで!! (私のホスト上で)。

あなたはチェックすることができます echo $ans、交換する"now"ことにより、"2019-25-12 20:10:00"およびように...

オプションで、日付サブプロセスが一度必要になると、終了し。

exec 5>&- ; exec 6<&-

元の投稿(詳細な説明)

変換するために日付ごとに 1つのフォークを実行する代わりに、date1回だけ実行し、すべての変換を同じプロセスで実行します(これはかなり速くなる可能性があります)!:

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"

これは1回の実行で行われました。

長時間実行を使用するサブプロセスの

fifoは1つだけ必要です。

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/MariaDBPostgreSQLおよびSQLite ...

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

2

使用するタイムゾーンを確認してください。

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
Mayur Gite

あなたもそれを使うことができます。dateこの入力を適切にフォーマットします。
Tajni
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.