Jak uzyskać sformatowaną datę znacznika czasu UNIX z wiersza polecenia

59

Mam znacznik czasu UNIX i chciałbym uzyskać sformatowaną datę (np. Wynik date) odpowiadającą temu znacznikowi czasu.

Moje dotychczasowe próby:

$ date +%s
1282367908
$ date -d 1282367908
date: invalid date `1282367908'
$ date -d +1282367908
date: invalid date `+1282367908'
$ date +%s -d +1282367908
date: invalid date `+1282367908'

Chciałbym móc uzyskać dane wyjściowe takie jak:

$ TZ=UTC somecommand 1282368345
Sat Aug 21 05:25:45 UTC 2010
Umang
źródło

Odpowiedzi:

91

W systemie Mac OS X i BSD:

$ date -r 1282368345
Sat Aug 21 07:25:45 CEST 2010
$ date -r 1282368345 +%Y-%m-%d
2010-08-21

za pomocą podstawowych narzędzi GNU (w tym celu musisz przekopać plik informacyjny):

$ date -d @1282368345
Sat Aug 21 07:25:45 CEST 2010
$ date -d @1282368345 --rfc-3339=date
2010-08-21

Z albo dodaj -uopcję (standard), albo przekaż TZ=UTC0zmienną środowiskową, aby mieć datę UTC ( TZ=UTC0 definiuje strefę czasową wywoływaną UTCz przesunięciem 0 od UTC, podczas gdy zachowanie dla TZ=UTC(bez przesunięcia) jest nieokreślone (chociaż w większości systemów odnosi się do zdefiniowana przez system strefa czasowa wywoływana również UTCz przesunięciem 0 od UTC)).

Stéphane Chazelas
źródło
1
Jednak wymaga to dużo kopania, co jest zaskakujące w przypadku tak powszechnego zadania.
David Z
Dzięki, zaakceptowałem twoją odpowiedź. Powinienem był przeczytać info coreutils datetrochę uważniej.
Umang,
Daje mi to nieco inną datę: date -r 1447264553943wynika z tego Wed Dec 28 01:39:03 BRST 47831, kiedy faktycznie jest 11/11/2015, 3:55:53 PM GMT-2:00.
falmp
1
@falmp: zadziała, jeśli użyjesz sekund zamiast mikrosekund.
@hop ops, powinienem był pomyśleć, że rok to 47831, ale liczba ta była tak wysoka, że ​​ją przegapiłem. Dzięki!
falmp
6

Po pewnym googlowaniu znalazłem sposób, aby to zrobić tylko za pomocą datepolecenia:

$ date --date "Jan 1, 1970 00:00:00 +0000 + 1282367908 seconds"
Sat Aug 21 09:18:28 MSD 2010
AlexD
źródło
Dziękuję za to. Miałem nadzieję, że będzie coś prostszego, więc na razie głosuj pozytywnie.
Umang,
kolejny świetny przykład tego, jak Google sprawia, że ​​jesteś głupi. czy nikt już nie czyta dokumentacji?
1
@hop, wsparcie dla date -d @xxxnie zostało dodane aż do coreutils 5.3 w 2005 roku. Tak właśnie musiałeś to zrobić wcześniej.
Stéphane Chazelas
@ StéphaneChazelas: a) ta odpowiedź pochodzi z 2010 r. I b) dlaczego ta wymówka googluje przed przeczytaniem dokumentacji? Jeśli odpowiesz od swojego autorytetu, możesz usprawiedliwić popełnienie takich błędów, ale jeśli i tak musisz to sprawdzić, sprawdź to.
@hop, właśnie wskazałem, że to nie była głupia odpowiedź, tylko przestarzała.
Stéphane Chazelas,
6

Ten perl-one-liner zrobi to:

$ perl -e 'print scalar localtime $ARGV[0]' 1282367908
Sat Aug 21 09:18:28 2010
AlexD
źródło
5

Z wbudowanymi powłokami:

  • zsh (4.1.1 (2003) i wyżej):

    $ zmodload zsh/datetime
    $ TZ=UTC0 strftime %c 1282368345
    Sat 21 Aug 2010 05:25:45 UTC
    
  • ksh93( ksh93i(2000) i wyżej):

    $ TZ=UTC0 printf '%(%c)T\n' '#1282368345'
    Sat Aug 21 05:25:45 2010
    
  • bash (4.2 (2010) i wyżej):

    $ TZ=UTC0 printf '%(%c)T\n' 1282368345
    Sat 21 Aug 2010 05:25:45 UTC
    

We wszystkich zamień %cna strftime()żądany format.

Stéphane Chazelas
źródło
Czy masz referencję do bash printfrozwiązania?
Derek Mahar,
Nieważne, znalazłem to w opisie printfw gnu.org/software/bash/manual/bashref.html#Bash-Builtins .
Derek Mahar,
2

Na OSX, aby mieć w UTC

date -r "1475737200" -u
ktoś
źródło
Dzięki. Zredagowałem to w zaakceptowanej odpowiedzi, aby informacje były łatwiej dostępne.
Stéphane Chazelas,
1

Kolejny zgrabny przykład bogatego dziedzictwa współczesnego Uniksa. Jest to rzeczywiście możliwe w przypadku większości wariantów BSD:

$ TZ=UTC date -r 1282368345
Sat Aug 21 05:25:45 UTC 2010

(BTW twój przykład wydaje się być wyłączony o jedną sekundę)

kodhead
źródło
Nie działa w systemie Linux. Wydaje się, że odpowiedź hopa zawiera poprawną odpowiedź dla systemu Linux. Dzięki za zwrócenie na to uwagi. Podejrzewałem, że coś takiego się wydarzy, zrobiłem to już 45 sekund.
Umang,
1

Odpowiedz na stare pytanie, ale myślę, że może to być poprawa, jeśli ktoś tego szuka. Ta funkcja Bash działa zarówno w systemie Linux, jak i OS X. Nie testowałem na żadnym innym systemie BSD. Podaj czas epoki jako argument dla tej funkcji, a wypisze format czasu RFC-3339.

epochtorfc3339 ()
{
    RFC3339_FORMAT="+%FT%T:::%z"
    EPOCH=$(echo $@ | sed -n "s/.*\([0-9]\{10\}\).*/\1/p");
    if date --version >/dev/null 2>/dev/null; then
        # Linux
        date ${RFC3339_FORMAT} -d "1970-01-01 UTC ${EPOCH} seconds"
        #date -d @${EPOCH} --rfc-3339=seconds
    else
        # OS X/BSD
        date -r ${EPOCH} ${RFC3339_FORMAT}
    fi
}
Noah Spurrier
źródło