Перетворити рядок дати і часу на епоху в Bash


94

Рядок дати і дати має такий формат: 06/12/2012 07:21:22. Як я можу перетворити його на часову позначку або епоху UNIX?

Відповіді:


95

Те, що ви шукаєте date --date='06/12/2012 07:21:22' +"%s". Майте на увазі, що це передбачає, що ви використовуєте GNU coreutils, оскільки обидва --dateі %sрядок формату є розширеннями GNU. POSIX не вказує жодного з них, тому немає переносного способу зробити таке перетворення навіть у системах, сумісних з POSIX.

Зверніться до відповідної сторінки інструкції щодо інших версій date.

Примітка: Баш --dateі -dваріант очікує дату в форматі ISO8601 або США, тобто mm/dd/yyyyабо yyyy-mm-dd, а не у Великій Британії, ЄС, або в будь-якому іншому форматі.


9
Я отримую "дату: незаконний варіант -", коли я працюю на Mac OSX 10.8.2
Бен Клейтон,

6
Для таких нубів, як я, +"%s"означає вихідний формат і %sце формат часу в секундах з 1970 р.
razz,

2
Примітка: якщо ви хочете вказати час в іншому часовому поясі (наприклад, UTC), додайте -HHMM або + HHMM до кінця. Тож date --date='06/12/2012 07:21:22 -0000' +"%s"перетворює дату UTC на позначку часу unix
Грег Брей,

Щодо дати GNU, якщо ви хочете скористатися UTC, зверніть увагу, що формат - yyyy-mm-dd hh:mm:ssподивіться на gnu.org/software/coreutils/manual/html_node/… :gdate --date='2019-06-18 00:02:00 +0000' +%s
Ашутош

не працює на Mac ... Цікаво, чи є спосіб працювати як на Mac, так і на Linux
nonopolarity

49

Для Linux Виконайте цю команду

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

Для Mac OSX виконайте цю команду

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

1
На OSX мітка часу якось збільшується з поточним часом. Наразі я не маю пояснення цього ...
polym

3
Оновлення: Це було тому, що воно регулює -uпозначку часу для мого місцевого часу, я думаю ... Додавання прапора повинно це виправити.
polym

@AbdulRehmanJanjua -uпрапор повинен прийти перш , ніж на -fпрапорі чи інакше тлумачить оболонки це формат рядка. Отже, це має бути:date -j -u -f "%a..."

4
Вставити саме те, що в терміналі macOS, не вдається.
zneak

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

10

Багато з цих відповідей занадто складні, а також відсутні способи використання змінних. Ось як ви могли б зробити це простіше у стандартній системі Linux (як уже згадувалося раніше, команду date потрібно було б налаштувати для користувачів Mac):

Приклад сценарію:

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

Призводить до :

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

Або як функція:

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

5
Ласкаво просимо до Stack Overflow. Подумайте про додавання пояснення на додаток до коду.
Олів'є Де Мольдер,

2

Ефективне рішення з використанням dateяк фонового виділеного процесу

Для того, щоб зробити такий переклад набагато швидшим ...

Вступ

У цій публікації ви знайдете

  • Quick Demo , слідом за цим,
  • деякі пояснення ,
  • функція корисної для багатьох Un * х інструментів ( bc, rot13, sed...).

Швидка демонстрація

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

Це повинно виводити поточний UNIXTIME . Звідти можна порівняти

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

і:

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

Від більш ніж 6 секунд до менш ніж півтори секунди !! (на моєму хості).

Ви можете перевірити echo $ans, замінити "now"на "2019-25-12 20:10:00"і так далі ...

За бажанням, після закінчення вимоги про підпроцес дати ви можете :

exec 5>&- ; exec 6<&-

Оригінальна публікація (детальне пояснення)

Замість того, щоб запускати 1 форк за датою для конвертації, запустіть dateлише 1 раз і виконайте всі перетворення одним і тим же процесом (це може стати набагато швидше)!

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

Зразок:

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

Тоді подивіться:

declare -p start1 start2 dirchg userdate

(може відповісти приблизно так:

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

Це було зроблено за одну страту!

Використовуючи тривалий біг підпроцесу

Нам потрібен лише один файл :

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

(Примітка: Оскільки процес запущений і всі дескриптори відкриті, ми можемо безпечно видалити запис файлової системи fifo.)

Тоді зараз:

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

Ми могли б придбати невелику функцію:

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

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

Або скористайтеся моїм newConnector функцією

З функціями для підключення MySQL/MariaDB , PostgreSQLіSQLite ...

Ви можете знайти їх в іншій версії на GitHub або на моєму сайті: завантажити або показати .

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

Увага: На GitHub функції та тест - це окремі файли. На моєму сайті випробувань виконуються просто , якщо цей сценарій не отримано .

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

2

Тільки будьте впевнені, який часовий пояс ви хочете використовувати.

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

Найпопулярнішим використанням є часовий пояс машини.

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

Але якщо ви навмисно хочете передати дату і час UTC і вам потрібний належний часовий пояс, вам потрібно додати -uпрапор. В іншому випадку ви конвертуєте його з місцевого часового поясу.

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

Що робити, якщо формат моєї дати - "РРРР мммдд"? напр. 20200827
Mayur Gite,

Ви можете також використовувати його. dateналежним чином форматує цей вхід.
Таджні
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.