Як я можу отримати відформатовану дату для часової позначки UNIX з командного рядка


59

У мене є часова марка UNIX, і я хотів би отримати відформатовану дату (наприклад, вихід date), відповідну цій часовій марці.

Мої спроби поки що:

$ 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'

Мені б хотілося отримати результат, наприклад:

$ TZ=UTC somecommand 1282368345
Sat Aug 21 05:25:45 UTC 2010

Відповіді:


91

У Mac OS X та BSD:

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

за допомогою основних інструментів GNU (для цього потрібно перекопати файл інформації):

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

З будь-яким -uваріантом додайте параметр (стандартний) або передайте TZ=UTC0змінну оточуючого середовища, щоб мати дату UTC ( TZ=UTC0 визначає часовий пояс, викликаний UTCзсувом 0 від UTC, тоді як поведінка для TZ=UTC(без зміщення) не визначено (хоча в більшості систем посилається на визначений системою часовий пояс також викликається UTCзі зміщенням 0 від UTC)).


1
Хоча потрібно багато копати, що дивно для такого поширеного завдання.
David Z

Дякуємо, прийняли вашу відповідь. Я повинен був прочитати info coreutils dateтрохи уважніше.
Умань

Це дає мені трохи іншу дату: date -r 1447264553943результати Wed Dec 28 01:39:03 BRST 47831, коли це насправді 11/11/2015, 3:55:53 PM GMT-2:00.
falmp

1
@falmp: він працюватиме, якщо замість мікросекунд використовувати секунди.

@hop ops, мав би розібратися з роком 47831, але це число було настільки великим, що я його пропустив. Дякую!
falmp

6

Після деякого гуглінгу я знайшов спосіб зробити це dateлише командою:

$ date --date "Jan 1, 1970 00:00:00 +0000 + 1282367908 seconds"
Sat Aug 21 09:18:28 MSD 2010

Дякую за це. Я сподівався, що буде щось простіше, тому поки що проголосуйте.
Умань

ще один чудовий приклад того, як Google робить вас дурними. ніхто більше ніколи не читає документацію?

1
@hop, підтримка date -d @xxxне була додана до coreutils 5.3 в 2005 році. Ось як це потрібно було робити до цього.
Стефан Шазелас

@ StéphaneChazelas: а) ця відповідь є з 2010 року, і б) чому це виправдання гуглю перед тим, як прочитати документацію? Якщо ви відповідаєте від своїх владних повноважень, ви можете виправдати подібні помилки, але якщо вам все одно доведеться їх шукати, шукайте їх правильно.

@hop, я просто вказував, що це не дурна відповідь, а лише застаріла.
Стефан Шазелас

6

Цей однолінійний Perl зробить це:

$ perl -e 'print scalar localtime $ARGV[0]' 1282367908
Sat Aug 21 09:18:28 2010

5

З вбудованими оболонками:

  • zsh (4.1.1 (2003) і вище):

    $ zmodload zsh/datetime
    $ TZ=UTC0 strftime %c 1282368345
    Sat 21 Aug 2010 05:25:45 UTC
    
  • ksh93( ksh93i(2000) і вище):

    $ TZ=UTC0 printf '%(%c)T\n' '#1282368345'
    Sat Aug 21 05:25:45 2010
    
  • bash (4.2 (2010) і вище):

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

В усіх цих випадках замініть %cпотрібний strftime()формат.


Чи є у вас посилання на bash printfрішення?
Дерек Махар

Не маючи уваги, я знайшов це в описі printfв gnu.org/software/bash/manual/bashref.html#Bash-Builtins .
Дерек Махар


1

Ще один акуратний приклад багатої спадщини сучасного Unix. Це дійсно можливо в більшості варіантів BSD:

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

(До речі, ваш приклад здається вимкненим на одну секунду)


Не працює в Linux. Відповідь скакання, схоже, має правильну відповідь Linux. Дякую, що вказав на це, я підозрював, що щось подібне станеться, я зробив це вже 45 секунд.
Умань

1

Відповідь на старе запитання, але я думаю, що це може бути покращенням, якщо хтось ще шукатиме цього. Ця функція Bash працює як на Linux, так і на OS X. Я не тестував жодних інших систем BSD. Передайте епоху час як аргумент цій функції, і він надрукує формат часу 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
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.