Как установить текущее время 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 будет правильно установлено в секундах с точностью до миллисекунды.

Другие вопросы по тегам