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

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


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

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

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.


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

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


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
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.