Konversikan string waktu tanggal menjadi epoch di Bash

95

String waktu tanggal dalam format berikut: 06/12/2012 07:21:22. Bagaimana cara mengubahnya menjadi stempel waktu UNIX atau epoch?

Edward D.
sumber

Jawaban:

96

Apa yang Anda cari adalah date --date='06/12/2012 07:21:22' +"%s". Ingatlah bahwa ini mengasumsikan Anda menggunakan GNU coreutils, karena keduanya --datedan %sstring formatnya adalah ekstensi GNU. POSIX tidak menentukan salah satu dari itu, jadi tidak ada cara portabel untuk membuat konversi seperti itu bahkan pada sistem yang sesuai dengan POSIX.

Lihat halaman manual yang sesuai untuk versi lain date.

Catatan: bash --datedan -dopsi mengharapkan tanggal dalam format AS atau ISO8601, yaitu mm/dd/yyyyatau yyyy-mm-dd, bukan di Inggris Raya, UE, atau format lainnya.

Daniel Kamil Kozar
sumber
9
Saya mendapatkan 'tanggal: opsi ilegal -' ketika saya menjalankan Mac OSX 10.8.2
Ben Clayton
6
Untuk noobs seperti saya +"%s"adalah singkatan dari format output dan %smerupakan format waktu dalam hitungan detik sejak 1970
razz
2
Catatan: jika Anda ingin menentukan waktu di zona waktu lain (seperti UTC), tambahkan -HHMM atau + HHMM di akhir. Jadi, date --date='06/12/2012 07:21:22 -0000' +"%s"
Greg Bray
Untuk tanggal GNU, jika Anda ingin menggunakan UTC perhatikan bahwa formatnya adalah yyyy-mm-dd hh:mm:sslihat di gnu.org/software/coreutils/manual/html_node/… :gdate --date='2019-06-18 00:02:00 +0000' +%s
Ashutosh Jindal
tidak berfungsi di Mac ... Saya ingin tahu apakah ada cara untuk bekerja di Mac dan Linux
nonopolaritas
50

Untuk Linux Jalankan perintah ini

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

Untuk mac OSX, jalankan perintah ini

date -j -u -f "%a %b %d %T %Z %Y" "Tue Sep 28 19:35:15 EDT 2010" "+%s"
Abdul Rehman Janjua
sumber
1
Di OSX, cap waktu meningkat entah bagaimana dengan waktu saat ini. Saat ini saya tidak memiliki penjelasan untuk itu ...
polym
3
Pembaruan: Itu karena itu menyesuaikan stempel waktu untuk waktu lokal saya, saya kira ... Menambahkan -ubendera harus memperbaikinya.
polym
@AbdulRehmanJanjua The -ubendera harus datang sebelum para -fbendera, atau yang lain yang menafsirkan shell itu format string. Jadi, seharusnya:date -j -u -f "%a..."
5
Gagal menempel tepat di terminal macOS.
zneak
7
date -jf "%Y-%m-%d %H:%M:%S" "2018-01-08 14:45:00" +%s
daviestar
10

Banyak dari jawaban ini terlalu rumit dan juga tidak ada cara menggunakan variabel. Beginilah cara Anda melakukannya dengan lebih sederhana pada sistem Linux standar (seperti yang disebutkan sebelumnya, perintah tanggal harus disesuaikan untuk Pengguna Mac):

Contoh skrip:

#!/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"

Hasil dalam:

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

Atau sebagai fungsi:

# -- 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
}
Mike Q
sumber
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
}
shgurbanov.dll
sumber
6
Selamat datang di Stack Overflow. Pertimbangkan untuk menambahkan penjelasan selain kode Anda.
Olivier De Meulder
2

Solusi yang efisien digunakan datesebagai proses khusus latar belakang

Untuk membuat terjemahan semacam ini lebih cepat ...

Intro

Di posting ini, Anda akan menemukan

  • sebuah Cepat Demo , berikut ini,
  • beberapa Penjelasan ,
  • a Fungsi bisa digunakan untuk banyak Un * x alat ( bc, rot13, sed...).

Demo Cepat

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

Ini harus mengeluarkan UNIXTIME saat ini . Dari sana, Anda bisa membandingkan

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

dan:

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

Dari lebih dari 6 detik menjadi kurang dari setengah detik !! (pada tuan rumah saya).

Anda dapat memeriksa echo $ans, mengganti "now"dengan"2019-25-12 20:10:00" dan seterusnya ...

Opsional, Anda bisa, setelah persyaratan subproses tanggal berakhir:

exec 5>&- ; exec 6<&-

Posting asli (penjelasan rinci)

Alih-alih menjalankan 1 percabangan berdasarkan tanggal untuk mengonversi, jalankan datehanya 1 kali dan lakukan semua konversi dengan proses yang sama (ini bisa menjadi jauh lebih cepat) !:

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

Sampel:

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

Kemudian sekarang lihat:

declare -p start1 start2 dirchg userdate

(mungkin menjawab sesuatu seperti:

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

Ini dilakukan dalam satu eksekusi!

Menggunakan subproses yang berjalan lama

Kami hanya membutuhkan satu fifo :

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

(Catatan: Saat proses sedang berjalan dan semua deskriptor dibuka, kami dapat dengan aman menghapus entri sistem file fifo.)

Kemudian sekarang:

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

Kita bisa membangun sedikit fungsi:

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

mydate start1 $(LANG=C ps ho lstart 1)
echo $start1

Atau gunakan fungsi saya newConnector

Dengan fungsi untuk menghubungkan MySQL/MariaDB , PostgreSQLdanSQLite ...

Anda dapat menemukannya dalam versi yang berbeda di GitHub , atau di situs saya: unduh atau tampilkan .

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

Catatan: Di GitHub , fungsi dan pengujian adalah file yang terpisah. Di situs saya, pengujian dijalankan hanya jika skrip ini tidak bersumber .

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

Pastikan saja zona waktu yang ingin Anda gunakan.

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

Penggunaan paling populer membutuhkan zona waktu mesin.

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

Tetapi jika Anda dengan sengaja ingin melewati waktu UTC dan Anda ingin zona waktu yang tepat, Anda perlu menambahkan -ubendera. Jika tidak, Anda mengubahnya dari zona waktu lokal Anda.

date -u -d "$datetime" +"%s" #general output = "1339485682"
Tajni
sumber
Bagaimana jika format tanggal saya adalah "YYYYmmdd"? ex. 20200827
Mayur Gite
Anda juga bisa menggunakannya. datememformat input ini dengan benar.
Tajni