使用内置的printf打印当前时间(以毫秒或纳秒为单位)

时间:2019-03-31 00:47:37

标签: linux bash datetime printf

我们可以使用内置的printf函数来打印当前时间,而无需调用date这样的外部命令,如下所示:

printf '%(%Y-%m-%d:%H:%M:%S)T %s\n' -1
# sample output: 2019-03-30:17:39:36,846

我们如何使printf也可以打印毫秒或纳秒?在格式字符串中使用%3N%N无效:

printf '%(%Y-%m-%d:%H:%M:%S,%3N)T %s\n' -1 # outputs 2019-03-30:17:38:16,%3N
printf '%(%Y-%m-%d:%H:%M:%S,%N)T %s\n' -1  # outputs 2019-03-30:17:38:16,%N

但是,date命令可以正常工作:

date +%Y-%m-%d:%H:%M:%S,%3N # gives 2019-03-30:17:39:36,846
date +%Y-%m-%d:%H:%M:%S,%N  # gives 2019-03-30:17:39:36,160643077

这是在Red Hat Linux 7.3版上。

2 个答案:

答案 0 :(得分:1)

bash 5中,您可以从EPOCHREALTIME获得微秒精度。但是,printf本身无法直接访问它,因此您需要自己提取微秒。

$ echo $EPOCHREALTIME; printf '%(%F:%T)T.%d\n' "$EPOCHSECONDS" "${EPOCHREALTIME#*.}"; echo $EPOCHREALTIME
1554006709.936990
2019-03-31:00:31:49.937048
1554006709.937083

这需要一些时间,但是结果似乎准确到大约0.05毫秒。

答案 1 :(得分:1)

V5和$EPOCHREALTIME

正确的方法:

IFS=. read ESEC NSEC <<<$EPOCHREALTIME
printf '%(%F:%T)T.%06.0f\n' $ESEC $NSEC

关于$EPOCHREALTIME

请注意:

    EPOCHREALTIME
         Each time this parameter is referenced, it expands to the number
         of seconds since the Unix Epoch  (see  time(3))  as  a  floating
         point  value  with  micro-second  granularity.

所以:

echo $EPOCHREALTIME...  $EPOCHREALTIME 
1572000683.886830... 1572000683.886840

或更清楚地是:

printf "%s\n" ${EPOCHREALTIME#*.} ${EPOCHREALTIME#*.}
761893
761925

因此,查询这两次以建立整数部分和小数部分是分开的过程可能会导致一个问题:(在同一行上,首先访问$ EPOCHREALTIME可以得到:NNN1.999995,然后是第二个:{{ 1}}。结果将变为:NNN2.000002出现 1000000 微秒错误)

关于混合NNN1.000002$EPOCHSECONDS

同时使用它们不仅会导致首次提到的错误!

由于$EPOCHREALTIME使用整数$EPOCHSECONDS内部变量(四舍五入),而$NOW使用对$EPOCHREALTIME的调用,结果可能会有很大不同:

如果我在主机上尝试:

gettimeofday

这将呈现:

errcnt=6 v1=$EPOCHSECONDS v2=$EPOCHREALTIME
while [ "$v1" = "${v2%.*}" ] || ((errcnt--));do
    read -t .0002
    v1=$EPOCHSECONDS v2=$EPOCHREALTIME
    echo $v1 ${v2%.*} - ${v2#*.}
  done | tail

1572522526 1572522526 - 999337 1572522526 1572522526 - 999621 1572522526 1572522526 - 999905 1572522526 1572522527 - 000192 1572522526 1572522527 - 000488 1572522526 1572522527 - 000779 1572522526 1572522527 - 001070 1572522526 1572522527 - 001360 1572522526 1572522527 - 001667 1572522526 1572522527 - 001950 的整数部分在$EPOCHREALTIME之前增加了2000微秒。

因此请避免同时使用!

关于$EPOCHSECONDS

注意:我使用printf "..%06.0f"而不是%06.0f以确保将%d解释为十进制(浮点数),(如果变量以$NSEC开头,则应防止八进制解释)

比较:

0

printf "nn.%06.0f\n" 012345
nn.012345

printf "nn.%06.0f\n" 098765
nn.098765

样品运行

小测试(注意:我没有使用printf "nn.%d\n" 012345 nn.5349 printf "nn.%d\n" 098765 -bash: printf: 098765: invalid octal number nn.0 ,而是使用read -t,因为sleep不是内置的):

sleep

您可以通过按 Return

结束此测试
while ! read -t .$((1000000-10#${EPOCHREALTIME#*.})) foo; do
    IFS=. read ESEC NSEC <<< $EPOCHREALTIME;
    printf '%(%F:%T)T.%06.0f\n' $ESEC $NSEC;
done