Bash'te tarih saat dizesini çağa dönüştür


95

Tarih saat dizesi şu formattadır: 06/12/2012 07:21:22. Bunu UNIX zaman damgasına veya epoch'a nasıl dönüştürebilirim?

Yanıtlar:


96

Aradığınız şey date --date='06/12/2012 07:21:22' +"%s". Her ikisi --dateve %sbiçim dizesi GNU uzantıları olduğu için , bunun GNU çekirdek işlevlerini kullandığınızı varsaydığını unutmayın . POSIX bunlardan hiçbirini belirtmez, bu nedenle POSIX uyumlu sistemlerde bile böyle bir dönüştürme yapmanın taşınabilir bir yolu yoktur.

Diğer sürümleri için uygun kılavuz sayfasına bakın date.

Not: bash --dateve -dopsiyon yani ABD veya ISO8601 biçiminde tarihini bekler mm/dd/yyyyveya yyyy-mm-dddeğil İngiltere'de, AB veya diğer herhangi bir formatta.


9
Mac OSX 10.8.2'de çalıştırdığımda 'date: illegal option -' mesajı alıyorum
Ben Clayton

6
Benim gibi çaylaklar +"%s"için çıktı formatı anlamına gelir ve %s1970'den beri saniye cinsinden zaman formatıdır
razz

2
Not: Saati başka bir saat diliminde (UTC gibi) belirtmek istiyorsanız sonuna -HHMM veya + HHMM ekleyin. Böylece date --date='06/12/2012 07:21:22 -0000' +"%s"UTC tarihini unix zaman damgasına dönüştürür
Greg Bray

GNU tarihi için, UTC'yi kullanmak isterseniz, formatın gnu.org/software/coreutils/manual/html_node/… 'yyyy-mm-dd hh:mm:ss a bir göz atmanız gerektiğini unutmayın :gdate --date='2019-06-18 00:02:00 +0000' +%s
Ashutosh Jindal

Mac üzerinde çalışmaz ... Bir Mac ve Linux üzerinde hem çalışmak için bir yol olup olmadığını merak
nonopolarity

50

Linux için Bu komutu çalıştırın

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

Mac OSX için bu komutu çalıştırın

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

1
OSX'te zaman damgası mevcut zamanla bir şekilde artar. Şu anda bunun için bir açıklamam yok ...
polim

3
Güncelleme: Bunun nedeni, yerel zamanımın zaman damgasını ayarlamasıydı sanırım ... Bir -ubayrak eklemek bunu düzeltmeli.
polym

@AbdulRehmanJanjua -uBayrak , bayraktan önce gelmelidir -f, aksi takdirde kabuk onu biçim dizesi olarak yorumlar. Öyleyse, şöyle olmalıdır:date -j -u -f "%a..."

5
Bir macOS terminaline tam olarak yapıştırmak başarısız olur.
zneak

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

10

Bu cevapların çoğu aşırı derecede karmaşık ve değişkenlerin nasıl kullanılacağını da kaçırıyor. Standart Linux sisteminde bunu daha basit bir şekilde yaparsınız (daha önce belirtildiği gibi, date komutunun Mac Kullanıcıları için ayarlanması gerekirdi):

Örnek komut dosyası:

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

Sonuçlar:

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

Veya bir işlev olarak:

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

6
Stack Overflow'a hoş geldiniz. Kodunuza ek olarak bir açıklama eklemeyi düşünün.
Olivier De Meulder

2

Arka plana özel süreçdate olarak kullanılan verimli çözüm

Bu tür bir çeviriyi çok daha hızlı hale getirmek için ...

Giriş

Bu yazıda bulacaksın

  • Bir Hızlı Demosu , bunu müteakip,
  • Bazı açıklamalar ,
  • Bir Fonksiyon birçok kullanışlı Un * x araçları ( bc, rot13, sed...).

Hızlı 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

Bu, geçerli UNIXTIME çıktı vermelidir . Oradan karşılaştırabilirsin

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

ve:

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

6 saniyeden fazla saniyeden yarım saniyeye kadar !! (ev sahibimde).

Sen kontrol edebilir echo $ans, yerine "now"göre "2019-25-12 20:10:00"vb ...

İsteğe bağlı olarak, tarih alt işleminin gerekliliği sona erdiğinde şunları yapabilirsiniz:

exec 5>&- ; exec 6<&-

Orijinal gönderi (ayrıntılı açıklama)

Dönüştürmek için tarihe göre 1 çatal çalıştırmak yerine, dateyalnızca 1 kez çalıştırın ve tüm dönüştürmeyi aynı işlemle yapın (bu çok daha hızlı hale gelebilir) !:

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

Örneklem:

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

O zaman şimdi bir göz atın:

declare -p start1 start2 dirchg userdate

(şöyle bir cevap verebilir:

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

Bu tek bir infazda yapıldı!

Uzun süren alt süreci kullanma

Sadece bir elliye ihtiyacımız var :

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

(Not: İşlem çalışırken ve tüm tanımlayıcılar açıldığında, fifo'nun dosya sistemi girişini güvenli bir şekilde kaldırabiliriz.)

Öyleyse şimdi:

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

Küçük bir işlev inşa edebiliriz:

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

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

Veya kullanmak benim newConnector işlevi

İle fonksiyonlar için bağlantı MySQL/MariaDB , PostgreSQLve SQLite...

Bunları GitHub'da veya sitemde farklı sürümlerde bulabilirsiniz : indirin veya gösterin .

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: On GitHub'dan , fonksiyonlar ve test dosyaları ayrılır. On sitemde bu komut değilse testi basitçe çalıştırılır kaynaklı .

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

2

Sadece hangi saat dilimini kullanmak istediğinizden emin olun.

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

En popüler kullanım, makinenin saat dilimini alır.

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

Ancak kasıtlı olarak UTC tarih saatini geçmek istiyorsanız ve uygun saat dilimini istiyorsanız, -ubayrak eklemeniz gerekir . Aksi takdirde, yerel saat diliminizden dönüştürürsünüz.

date -u -d "$datetime" +"%s" #general output = "1339485682"

Tarih formatım "YYYYaaaa" ise ne olur? ör. 20200827
Mayur Gite

Sen de kullanabilirsin. datebu girişi düzgün biçimlendirir.
Tajni
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.