Как я получаю текущее время Unix в миллисекундах в Bash?

Я рекомендую смотреть на представленный документ этого VMware, который это дает шансу вниз на огромном количестве OSs и указывает на любые потенциальные проблемы. Руководство Гостевой ОС

237
задан 18 November 2019 в 15:17
18 ответов

Это:

date +%s 

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

Это:

date +%s%N

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

Так:

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

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


и от MikeyB - echo $(($(date +%s%N)/1000000)) (деление на 1 000 только приносит к микросекундам),

270
ответ дан 28 November 2019 в 19:13
  • 1
    It' s принцип вопроса... избегают магических чисел и кодируют что Вы на самом деле средний . –  MikeyB 14 June 2010 в 10:02
  • 2
    Интересно, сколько мс добавляет сокращение :-) –  Kyle Brandt 14 June 2010 в 19:23
  • 3
    Или если Вы хотите сделать все это в оболочке, избегая дорогих издержек дополнительного процесса (на самом деле, we' ре, избегающее проблемы, когда количество цифр в % +s+N изменения): echo $(($(date +%s%N)/1000)) –  MikeyB 14 June 2010 в 19:38
  • 4
    Я думаю it' s стоящий замечания, что человек попросил Unix, не Linux и текущий главный ответ (дата + %s%N) doesn' t работают над моей системой AIX. –  Pete 25 October 2011 в 19:52

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

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

Теперь можно работать

TIMESTAMP="$(nowInMs)";
1
ответ дан 28 November 2019 в 19:13

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

echo $(($(date +%s%N)/1000000))
10
ответ дан 28 November 2019 в 19:13

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

# 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 специальные значения в течение времени.

2
ответ дан 28 November 2019 в 19:13

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

date +%s000

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

10
ответ дан 28 November 2019 в 19:13

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

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

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

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

basetime = $ (date +% s% N)

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

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

echo "время выполнения: $ (echo" scale = 3; ($ (date +% s% N) - $ {basetime}) / (1 * 10 ^ 09) "| bc) секунд"

, который будет отображать что-то вроде

время выполнения: 12,383 секунды

Примечания:

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

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

Я тестировал это только на Windows 7 / MinGW ... Я не

2
ответ дан 28 November 2019 в 19:13

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

$ date +%s%3N
1397392146866

Это работает, например, на моем Kubuntu 12.04 (Precise Pangolin).

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

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

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

105
ответ дан 28 November 2019 в 19:13

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

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

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

7
ответ дан 28 November 2019 в 19:13

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

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

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

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

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

1
ответ дан 28 November 2019 в 19:13

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

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

perl -w -e'use Time::Format; printf STDOUT ("%s.%s\n", time, $time{"mmm"})'
1
ответ дан 28 November 2019 в 19:13

Собирая все предыдущие ответы вместе, в 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"
}
1
ответ дан 28 November 2019 в 19:13

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

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

1490665305.021699

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

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

Можно не комментировать эхо-команды, чтобы посмотреть, как это работает.

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

measured seconds: 1.99
measured seconds: 2.00
measured seconds: 2.01
2
ответ дан 28 November 2019 в 19:13

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

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

#!/bin/bash

python -c 'from time import time; print int(round(time() * 1000))'
7
ответ дан 28 November 2019 в 19:13

Wenn Sie eine einfache Berechnung der abgelaufenen Shell wünschen, ist dies einfach und portabel. Verwenden Sie dazu die Antwort von Frank Thonig :

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
0
ответ дан 28 November 2019 в 19:13

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

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

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

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

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

0
ответ дан 28 November 2019 в 19:13

Еще одно решение для MacOS: GNU Coreutils

Я заметил, что версия команды date для MacOS не интерпретирует %N форматировать последовательность как наносекунды, а просто выводит N на вывод, когда я начал использовать мой скрипт .bashrc из Linux, который использует его для измерения того, как долго выполняются выполняемые команды , на машине MacOS.

После небольшого исследования я узнал, что только дата GNU из пакета GNU Coreutils поддерживает миллисекунды. К счастью, его довольно легко установить на MacOS с помощью Homebrew:

brew install coreutils

Поскольку этот пакет содержит исполняемые файлы, которые уже присутствуют в MacOS, исполняемые файлы Coreutils будут установлены с префиксом g, поэтому дата будет доступен как gdate.

Дополнительную информацию см., например, на этой странице.

0
ответ дан 8 May 2021 в 23:24

Perl-решение

perl -mTime::HiRes -e 'printf "%.0f\n", (Time::HiRes::time() * 1000 )'

Time::HiRes::time () возвращает число с плавающей запятой в формате unixtimeinsec.microseconds

Умножьте на 1000, чтобы сдвинуть влево на 3 цифры, и выведите без десятичных цифр.
Почему бы просто не преобразовать в целое число с помощью %d?
Поскольку это приведет к переполнению целого числа со знаком (или без знака) в 32-битной ОС, например как наши древние серверы AIX.

Как отмечали другие, это вопрос переносимости. Принятый ответ работает в Linux или во всем, что может запускать дату gnu, но не в некоторых других вариантах UNIX. Лично я считаю, что наши старые системы гораздо чаще используют Perl, чем Python, Node.js, Ruby или PHP.

Да, date +%s%3N (если доступно) примерно в 5 раз быстрее, чем perl).

1
ответ дан 14 July 2021 в 04:31

Теги

Похожие вопросы