可能的解决方案

可能的解决方案

可能的解决方案

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 执行需要几毫秒。我真正需要的是亚秒级的分辨率,十分之一秒就足够了。

答案1

这是一个解决方案(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二进制文件需要时间。对于所有 shell 和execinsert-higher-level-language-here 来说都是如此

然而,如果您只需要十分之一秒范围内的亚秒分辨率,那么在很多情况下这就足够了。

答案2

如果您的目标是以亚秒间隔设置时间,那么如果我正确阅读了源代码,那么日期似乎是错误的命令。

假设你正在使用核心工具版本的 date,那么在我看来,该when.tv_nsec = 0行将变量(timespec 结构)的纳秒部分设置when为零。即使您可以说服 date 接受更准确的值,在我看来,这也没有意义。

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

答案3

有一种更好的方法,不需要像接受的答案那样将时间戳转换为人类可读的日期格式。你非常接近你最初的建议:

date +"%s.%N" -s "1323217126.085882000"

当给出时间戳时,需要在前面加上“@”,就像这样,而不是用引号引起来:

date +"%s.%N" -s @1323217126.085882000

现在将以毫秒为精度正确设置当前 Linux 时间(以秒为单位)。

相关内容