可能的解决方案
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 和exec
insert-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 时间(以秒为单位)。