Konvertieren Sie Datums- und Uhrzeitzeichenfolge in Epoche in Bash


90

Die Datums- / Uhrzeitzeichenfolge hat das folgende Format: 06/12/2012 07:21:22. Wie kann ich es in einen UNIX-Zeitstempel oder eine Epoche konvertieren?

Antworten:


92

Was Sie suchen, ist date --date='06/12/2012 07:21:22' +"%s". Beachten Sie, dass dies voraussetzt, dass Sie GNU-Coreutils verwenden, da beide --dateund die %sFormatzeichenfolge GNU-Erweiterungen sind. POSIX gibt keines von beiden an, daher gibt es auch auf POSIX-kompatiblen Systemen keine tragbare Möglichkeit, eine solche Konvertierung durchzuführen.

Weitere Versionen von finden Sie auf der entsprechenden Handbuchseite date.

Hinweis: Bash --dateund -dOption erwarten das Datum im US- oder ISO8601-Format, dh mm/dd/yyyyoder yyyy-mm-ddnicht in Großbritannien, der EU oder einem anderen Format.


8
Ich erhalte 'Datum: illegale Option -', wenn ich unter Mac OSX 10.8.2
— Ben Clayton

6
Für Noobs wie mich +"%s"steht für Ausgabeformat und %sist das Format der Zeit in Sekunden seit 1970
— Razz

2
Hinweis: Wenn Sie die Zeit in einer anderen Zeitzone (wie UTC) angeben möchten, fügen Sie am Ende -HHMM oder + HHMM hinzu. Also date --date='06/12/2012 07:21:22 -0000' +"%s"konvertiert UTC Datum in Unix Zeitstempel
— Greg Bray

Für GNU Datum möchten , wenn Sie UTC Notiz verwenden , dass das Format yyyy-mm-dd hh:mm:sseinen Blick auf haben gnu.org/software/coreutils/manual/html_node/... :gdate --date='2019-06-18 00:02:00 +0000' +%s
— Ashutosh Jindal

funktioniert nicht auf einem Mac ... Ich frage mich, ob es eine Möglichkeit gibt, sowohl auf einem Mac als auch unter Linux zu arbeiten
— Unpolarität

47

Für Linux Führen Sie diesen Befehl aus

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

Führen Sie diesen Befehl unter Mac OSX aus

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

1
Unter OSX erhöht sich der Zeitstempel irgendwie mit der aktuellen Zeit. Ich habe derzeit keine Erklärung dafür ...
— Polym

3
Update: Das lag daran, dass der Zeitstempel für meine Ortszeit angepasst wird, denke ich ... Das Hinzufügen eines -uFlags sollte das beheben.
— Polym

@AbdulRehmanJanjua Das -uFlag sollte vor dem -fFlag stehen, sonst interpretiert die Shell es als Formatzeichenfolge . Also sollte es sein:date -j -u -f "%a..."

4
Das Einfügen genau in ein macOS-Terminal schlägt fehl.
— Zneak

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

10

Viele dieser Antworten sind zu kompliziert und es fehlt auch die Verwendung von Variablen. So würden Sie es auf einem Standard-Linux-System einfacher machen (wie bereits erwähnt, müsste der Datumsbefehl für Mac-Benutzer angepasst werden):

Beispielskript:

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

Ergebnisse in:

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

Oder als Funktion:

# -- 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
Willkommen bei Stack Overflow. Erwägen Sie, zusätzlich zu Ihrem Code eine Erklärung hinzuzufügen.
— Olivier De Meulder

2

Effiziente Lösung dateals Hintergrundprozess

Um diese Art der Übersetzung viel schneller zu machen ...

Intro

In diesem Beitrag finden Sie

  • eine kurze Demo , die folgt,
  • einige Erklärungen ,
  • eine Funktion nutzbar für viele Un * x - Tools ( bc, rot13, sed...).

Schnelle Demo

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

Dies muss die aktuelle UNIXTIME ausgeben . Von dort konnte man vergleichen

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

und:

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

Von mehr als 6 Sekunden bis weniger als einer halben Sekunde !! (auf meinem Gastgeber).

Sie könnten überprüfen echo $ans, ersetzen "now"durch"2019-25-12 20:10:00" und so weiter ...

Optional können Sie nach Beendigung der Anforderung des Datumsunterprozesses Folgendes tun:

exec 5>&- ; exec 6<&-

Originalbeitrag (ausführliche Erklärung)

Anstatt 1 Gabel nach Datum zum Konvertieren auszuführen, führen Sie datenur 1 Mal aus und führen Sie alle Konvertierungen mit demselben Prozess durch (dies könnte viel schneller werden)!:

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

Stichprobe:

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

Dann schauen Sie jetzt:

declare -p start1 start2 dirchg userdate

(kann etwas beantworten wie:

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

Dies geschah in einer Ausführung!

Verwenden eines lang laufenden Unterprozesses

Wir brauchen nur ein Fifo :

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

(Hinweis: Während der Prozess ausgeführt wird und alle Deskriptoren geöffnet sind, können wir den Dateisystemeintrag von fifo sicher entfernen.)

Dann jetzt:

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

Wir könnten eine kleine Funktion kaufen:

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

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

Oder benutze meine newConnector Funktion

Mit Funktionen für Anschluss MySQL/MariaDB , PostgreSQLundSQLite ...

Sie können sie in einer anderen Version auf GitHub oder auf meiner Website finden: herunterladen oder anzeigen .

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

Hinweis: Auf GitHub sind Funktionen und Test getrennte Dateien. Auf meiner Website Test werden läuft einfach , wenn dieses Skript ist nicht bezogen .

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

2

Stellen Sie einfach sicher, welche Zeitzone Sie verwenden möchten.

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

Die beliebteste Verwendung ist die Zeitzone der Maschine.

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

Wenn Sie jedoch absichtlich die UTC-Uhrzeit übergeben möchten und die richtige Zeitzone wünschen, müssen Sie ein -uFlag hinzufügen . Andernfalls konvertieren Sie es aus Ihrer lokalen Zeitzone.

date -u -d "$datetime" +"%s" #general output = "1339485682"
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.