Назад | Перейти на главную страницу

Как мне узнать текущее время Unix в миллисекундах в Bash?

Как мне узнать текущее время Unix в миллисекундах (то есть количество миллисекунд с эпохи Unix 1 января 1970 года)?

Это:

date +%s 

вернет количество секунды с эпохи.

Это:

date +%s%N

возвращает секунды и текущие наносекунды.

Так:

date +%s%N | cut -b1-13

даст вам количество миллисекунд с начала эпохи - текущие секунды плюс оставшиеся три наносекунды.


и из MikeyB - echo $(($(date +%s%N)/1000000)) (деление на 1000 дает только микросекунды)

Вы можете просто использовать %3N чтобы усечь наносекунды до 3-х наиболее значимых цифр (которые затем являются миллисекундами):

$ date +%s%3N
1397392146866

Это работает, например, на моем Кубунту 12.04 (точный панголин).

Но имейте в виду, что %N могут не быть реализованы в зависимости от вашей целевой системы. Например. протестировано на встроенной системе (buildroot rootfs, скомпилировано с использованием кросс-инструментальной цепочки, отличной от HF ARM), не было %N:

$ date +%s%3N
1397392146%3N

(А также мой (не рутированный) Android-планшет не имеет %N.)

date +%N не работает в OS X, но вы можете использовать один из

  • Рубин: ruby -e 'puts Time.now.to_f'
  • Python: python -c 'import time; print time.time()'
  • Node.js: node -e 'console.log(Date.now())'
  • PHP: php -r 'echo microtime(TRUE);'
  • Эликсир: DateTime.utc_now() |> DateTime.to_unix(:millisecond)
  • Интернет: wget -qO- http://www.timeapi.org/utc/now?\\s.\\N
  • или для миллисекунд с округлением до ближайшей секунды date +%s000

Мое решение не самое лучшее, но у меня оно сработало:

date +%s000

Мне просто нужно было преобразовать дату вроде 2012-05-05 в миллисекунды.

Просто выбросьте это туда, но я думаю, что правильная формула с делением будет:

echo $(($(date +%s%N)/1000000))

Это решение работает на macOS.

Если вы думаете об использовании сценария Bash и у вас есть Python, вы можете использовать этот код:

#!/bin/bash

python -c 'from time import time; print int(round(time() * 1000))'

Для людей, которые предлагают запускать внешние программы, чтобы получить Миллисекунд ... с такой скоростью вы можете сделать это:

wget -qO- http://www.timeapi.org/utc/now?\\s.\\N

Суть в том, что прежде чем выбирать какой-либо ответ отсюда, имейте в виду, что не все программы будут работать менее одной секунды. Измерьте!

Если вы ищете способ отобразить продолжительность выполнения сценария, следующий результат (не совсем точный) предоставит результат:

Как можно ближе к началу вашего скрипта введите следующее

basetime=$(date +%s%N)

Это даст вам начальное значение примерно 1361802943996000000.

В конце вашего скрипта используйте следующее

echo "runtime: $(echo "scale=3;($(date +%s%N) - ${basetime})/(1*10^09)" | bc) seconds"

который отобразит что-то вроде

runtime: 12.383 seconds

Ноты:

(1 * 10 ^ 09) при желании можно заменить на 1000000000

"scale=3" довольно редкая настройка, которая принуждает bc делать то, что хочешь. Есть еще много всего!

Я тестировал это только на Windows 7 / MinGW ... У меня нет под рукой подходящего модуля * nix.

Наиболее точная временная метка, которую мы можем получить (по крайней мере, для Mac OS X), вероятно, следующая:

python -c 'import datetime; print datetime.datetime.now().strftime("%s.%f")'

1490665305.021699

Но мы должны иметь в виду, что на выполнение требуется около 30 миллисекунд. Мы можем сократить его до двухзначной дроби и в самом начале вычислить средние накладные расходы считывания времени, а затем удалите его из измерения. Вот пример:

function getTimestamp {
  echo `python -c 'import datetime; print datetime.datetime.now().strftime("%s.%f")' | cut -b1-13` 
}
function getDiff {
  echo "$2-$1-$MeasuringCost" | bc
}
prev_a=`getTimestamp`
acc=0
ITERATIONS=30
for i in `seq 1 $ITERATIONS`;do 
  #echo -n $i 
  a=`getTimestamp`
  #echo -n "   $a"
  b=`echo "$a-$prev_a" | bc`
  prev_a=$a
  #echo "  diff=$b"
  acc=`echo "$acc+$b" | bc`
done
MeasuringCost=`echo "scale=2; $acc/$ITERATIONS" | bc`
echo "average: $MeasuringCost sec"
t1=`getTimestamp`
sleep 2
t2=`getTimestamp`
echo "measured seconds: `getDiff $t1 $t2`"

Вы можете раскомментировать команды эха, чтобы лучше понять, как они работают.

Результатом этого сценария обычно является один из следующих трех результатов:

measured seconds: 1.99
measured seconds: 2.00
measured seconds: 2.01

Не добавляя здесь ничего революционного по сравнению с принятым ответом, но просто для того, чтобы его можно было легко использовать повторно для тех из вас, кто новичок в Bash. Обратите внимание, что этот пример работает в OS X и более старом Bash, что было требованием лично для меня.

nowInMs() {
  echo "$(($(date +'%s * 1000 + %-N / 1000000')))"
}

Теперь ты можешь бежать

TIMESTAMP="$(nowInMs)";

Вот как получить время в миллисекундах без деления. Может быстрее ...

# test=`date +%s%N`
# testnum=${#test}
# echo ${test:0:$testnum-6}
1297327781715

Обновление: другая альтернатива в чистом Bash, которая работает только с Bash 4.2+, такая же, как указано выше, но используйте printf чтобы получить дату. Это определенно будет быстрее, потому что от основного не происходит никаких процессов.

printf -v test '%(%s%N)T' -1
testnum=${#test}
echo ${test:0:$testnum-6}

Еще одна загвоздка в том, что ваш strftime реализация должна поддерживать %s и %N который не чехол на моей тестовой машине. Видеть man strftime для поддерживаемых опций. Также см man bash увидеть printf синтаксис. -1 и -2 особые значения времени.

Используя дату и выражение, вы можете попасть туда, т.е.

X=$(expr \`date +%H\` \\* 3600 + \`date +%M\` \\* 60 + \`date +%S\`)
echo $X

Просто расширьте его, чтобы делать все, что хотите

Я понимаю, что это не дает миллисекунд с эпохи, но это все равно может быть полезно в качестве ответа в некоторых случаях, все зависит от того, для чего вам это действительно нужно, умножьте на 1000, если вам нужно число в миллисекундах: D

Самый простой способ - создать небольшой исполняемый файл (из C f.ex.) и сделать его доступным для сценария.

Собирая все предыдущие ответы вместе, в OS X

ProductName:    Mac OS X
ProductVersion:    10.11.6
BuildVersion:    15G31+

ты можешь делать как

microtime() {
    python -c 'import time; print time.time()'
}
compute() {
    local START=$(microtime)
    #$1 is command $2 are args
    local END=$(microtime)
    DIFF=$(echo "$END - $START" | bc)
    echo "$1\t$2\t$DIFF"
}

(повторить из предыдущих ответов) date +%N не работает в OS X, но вы также можете использовать:

Perl (требуется модуль Time :: Format). Возможно это не самое лучшее CPAN модуль для использования, но он выполняет свою работу. Time :: Format обычно доступен в дистрибутивах.

perl -w -e'use Time::Format; printf STDOUT ("%s.%s\n", time, $time{"mmm"})'

Если вам нужно простое вычисление, прошедшее через оболочку, это легко и переносимо, используя Ответ Фрэнка Тонига:

now() {
    python -c 'import datetime; print datetime.datetime.now().strftime("%s.%f")'
}
seismo:~$ x=`now`
seismo:~$ y=`now`
seismo:~$ echo "$y - $x" | bc
5.212514

Для Alpine Linux (многие образы Docker) и, возможно, другие минимальные среды Linux, вы можете злоупотреблять adjtimex:

adjtimex | awk '/(time.tv_usec):/ { printf("%06d\n", $2) }' | head -c3

adjtimex используется для чтения (и установки) переменных времени ядра. С участием awk вы можете получить микросекунды, а с head вы можете использовать только первые 3 цифры.

Понятия не имею, насколько надежна эта команда.

Примечание: бесстыдно украдено из этот ответ