Как установить текущее время Unix в миллисекундах?
Возможное решение
date --set="2011-12-07 01:20:15.962" && date --rfc-3339=ns
Оригинальный вопрос
Я могу получить дату с миллисекундами, например, так:
date +"%S.%N"
date --rfc-3339=ns
В соответствии с man date
Я ожидаю, что смогу установить это так:
date --set=%s.%N +`date +"%S.%N"`
date --set="%s.%N" "+1323217126.085882000"
В соответствии с моим поиском в Интернете, я ожидал, что смогу установить дату следующим образом (обратное приведенному выше):
date +%s.%N -s `date +"%S.%N"`
date +"%s.%N" -s "1323217126.085882000"
Ни одна из них не работает. Может кто-нибудь подсказать мне этот вопрос?
PS Нет, мне не нужно наносекундное разрешение. Да, я знаю, что выполнение bash занимает миллисекунды. Что мне действительно нужно, так это субсекундное разрешение, 10-х секунд будет достаточно.
3 ответа
Вот решение (Linux, НЕ Unix):
date --set="2011-12-07 01:20:15.962" && date --rfc-3339=ns
Обратите внимание на задержку:
CURTIME=`date --rfc-3339=ns`
date --set="${CURTIME}"
NEWTIME=`date --rfc-3339=ns`
echo ${CURTIME}
echo ${NEWTIME}
2011-12-07 01:48:54.687216122+00:00
2011-12-07 01:48:54.720541318+00:00
Как вы заметите, вводятся целые миллисекунды задержки. Это связано со временем, которое требуется для инициализации памяти и загрузки date
двоичный файл. Это верно для всех оболочек и exec
вставить язык более высокого уровня здесь
Однако, если вам просто нужно разрешение менее секунды в диапазоне десятых долей секунды, во многих случаях этого будет достаточно.
Если ваша цель состоит в том, чтобы установить время с интервалами в секунду, тогда дата кажется неправильной командой, если я правильно читаю источник.
Предполагая, что вы используете версию даты coreutils, мне кажется, что when.tv_nsec = 0
линия устанавливает наносекундную часть when
переменная, которая является временной структурой, равной нулю. Даже если бы вы могли убедить дату принять более точное значение, мне кажется, это было бы бессмысленно.
# time.h
struct timespec
{
__time_t tv_sec; /* Seconds. */
long int tv_nsec; /* Nanoseconds. */
};
# date.c
struct timespec when;
# ...
valid_date = posixtime (&when.tv_sec,
datestr,
(PDS_TRAILING_YEAR
| PDS_CENTURY | PDS_SECONDS));
when.tv_nsec = 0; /* FIXME: posixtime should set this. */
# ...
/* Set the system clock to the specified date, then regardless of
the success of that operation, format and print that date. */
if (settime (&when) != 0)
{
error (0, errno, _("cannot set date"));
ok = false;
}
Существует лучший метод, который не требует преобразования отметки времени в удобочитаемый формат даты, как в принятом ответе. Вы были очень близки к своему первоначальному предложению:
date +"%s.%N" -s "1323217126.085882000"
При указании временных меток вам необходимо добавлять префикс «@», а не цитировать их:
date +"%s.%N" -s @1323217126.085882000
Теперь текущее время Linux будет правильно установлено в секундах с точностью до миллисекунды.