Ciąg daty i godziny ma następujący format: 12.06.2012 07:21:22. Jak mogę przekonwertować go na sygnaturę czasową lub epokę UNIX?
95
To, czego szukasz, to date --date='06/12/2012 07:21:22' +"%s"
. Pamiętaj, że zakłada się, że używasz coreutils GNU, ponieważ oba elementy --date
i %s
łańcuch formatu są rozszerzeniami GNU. POSIX nie określa żadnego z nich, więc nie ma przenośnego sposobu na wykonanie takiej konwersji nawet w systemach zgodnych z POSIX.
Zapoznaj się z odpowiednią stroną podręcznika dla innych wersji date
.
Uwaga: bash --date
i -d
opcja oczekują daty w formacie amerykańskim lub ISO8601, tj. mm/dd/yyyy
Lub yyyy-mm-dd
nie w formacie brytyjskim, UE lub innym.
+"%s"
oznacza format wyjściowy i%s
jest to format czasu w sekundach od 1970 rokudate --date='06/12/2012 07:21:22 -0000' +"%s"
konwertuje datę UTC na znacznik czasu unixayyyy-mm-dd hh:mm:ss
z gnu.org/software/coreutils/manual/html_node/ ... :gdate --date='2019-06-18 00:02:00 +0000' +%s
W systemie Linux Uruchom to polecenie
date -d '06/12/2012 07:21:22' +"%s"
W systemie Mac OSX uruchom to polecenie
date -j -u -f "%a %b %d %T %Z %Y" "Tue Sep 28 19:35:15 EDT 2010" "+%s"
źródło
-u
flagi powinno to naprawić.-u
flaga powinna przyjść wcześniej na-f
flagi, albo też interpretuje powłoki to ciąg formatu. Tak więc powinno to być:date -j -u -f "%a..."
date -jf "%Y-%m-%d %H:%M:%S" "2018-01-08 14:45:00" +%s
Wiele z tych odpowiedzi jest zbyt skomplikowanych, a także brakuje w nich sposobu korzystania ze zmiennych. W ten sposób zrobiłbyś to prościej w standardowym systemie Linux (jak wspomniano wcześniej, polecenie date musiałoby być dostosowane do użytkowników komputerów Mac):
Przykładowy skrypt:
#!/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"
Prowadzi do :
Lub jako funkcja:
# -- 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 }
źródło
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 }
źródło
Wydajne rozwiązanie wykorzystujące
date
jako tło procesu przeznaczoneAby tego rodzaju tłumaczenie było dużo szybsze ...
Intro
W tym poście znajdziesz
bc
,rot13
,sed
...).Szybkie 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
Musi to wyprowadzać prąd UNIXTIME . Stamtąd możesz porównać
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
i:
time for i in {1..5000};do ans=$(date +%s -d "now");done real 0m6.826s user 0m0.256s sys 0m1.364s
Od ponad 6 sekund do mniej niż pół sekundy !! (na moim hoście).
Możesz sprawdzić
echo $ans
, wymienić"now"
na"2019-25-12 20:10:00"
i tak dalej ...Opcjonalnie możesz po zakończeniu wymagania daty podprocesu :
exec 5>&- ; exec 6<&-
Oryginalny post (szczegółowe wyjaśnienie)
Zamiast uruchamiać 1 fork według daty w celu konwersji, uruchom
date
tylko 1 raz i wykonaj całą konwersję w tym samym procesie (może to stać się znacznie szybsze) !:Próba:
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" )
A teraz spójrz:
declare -p start1 start2 dirchg userdate
Zrobiono to w jednym wykonaniu!
Korzystanie z długotrwałego podprocesu
Potrzebujemy tylko jednej kolejki FIFO :
mkfifo /tmp/myDateFifo exec 7> >(exec stdbuf -o0 /bin/date -f - +%s >/tmp/myDateFifo) exec 8</tmp/myDateFifo rm /tmp/myDateFifo
(Uwaga: ponieważ proces jest uruchomiony i wszystkie deskryptory są otwarte, możemy bezpiecznie usunąć wpis systemu plików fifo).
Więc teraz:
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
Moglibyśmy kupić małą funkcję:
mydate() { local var=$1; shift; echo >&7 $@ read -u 8 $var } mydate start1 $(LANG=C ps ho lstart 1) echo $start1
Lub użyj mojej
newConnector
funkcjiZ funkcjami do łączenia
MySQL/MariaDB
,PostgreSQL
iSQLite
...Możesz je znaleźć w innej wersji na GitHub lub na mojej stronie: pobierz lub pokaż .
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
Nota: Na GitHub , funkcje i testy są oddzielone plików. Na mojej stronie testy są uruchamiane po prostu, jeśli ten skrypt nie jest pochodzący .
# Exit here if script is sourced [ "$0" = "$BASH_SOURCE" ] || { true;return 0;}
źródło
Po prostu upewnij się, jakiej strefy czasowej chcesz używać.
datetime="06/12/2012 07:21:22"
Najpopularniejszym zastosowaniem jest strefa czasowa maszyny.
date -d "$datetime" +"%s" #depends on local timezone, my output = "1339456882"
Ale jeśli celowo chcesz przekazać datę UTC i chcesz mieć odpowiednią strefę czasową, musisz dodać
-u
flagę. W przeciwnym razie przekonwertujesz go z lokalnej strefy czasowej.date -u -d "$datetime" +"%s" #general output = "1339485682"
źródło
date
prawidłowo formatuje to wejście.