命令以毫秒为单位获取时间

Linux中是否有shell命令以毫秒为单位获取时间?

514719 次浏览

date +%s%N返回秒数+当前纳秒。

因此,echo $(($(date +%s%N)/1000000))是你所需要的。

例子:

$ echo $(($(date +%s%N)/1000000))
1535546718115

date +%s返回自纪元以来的秒数,如果有用的话。

  • date +"%T.%N"返回以纳秒为单位的当前时间。

    06:46:41.431857000
    
  • date +"%T.%6N" returns the current time with nanoseconds rounded to the first 6 digits, which is microseconds.

    06:47:07.183172
    
  • date +"%T.%3N" returns the current time with nanoseconds rounded to the first 3 digits, which is milliseconds.

    06:47:42.773
    

In general, every field of the date command's format can be given an optional field width.

像这样的Python脚本:

import time
cur_time = int(time.time()*1000)

Nano是10−9, milli是10−3。因此,我们可以使用纳秒的前三个字符来得到毫秒:

date +%s%3N

man date:

% N纳秒(000000000..999999999)

% s seconds since 1970-01-01 00:00:00 UTC

来源:服务器故障的如何在Bash中以毫秒为单位获得当前Unix时间?< / >

在OS X上,date不支持%N标志,我建议使用家酿安装coreutils。这将使你能够访问一个名为gdate的命令,其行为将与Linux系统上的date一样。

brew install coreutils

为了获得更“原生”的体验,你可以在.bash_aliases中添加这个:

alias date='gdate'

然后执行

$ date +%s%N

在大多数情况下,其他答案可能已经足够了,但我想当我在BusyBox系统上遇到问题时,我会补充我的意见。

该系统不支持%N格式选项,也没有Python或Perl解释器。

在绞尽脑汁之后,我们(感谢戴夫!)想出了这个:

adjtimex | awk '/(time.tv_sec|time.tv_usec):/ { printf("%06d", $2) }'

它从adjtimex的输出中提取秒和微秒(通常用于设置系统时钟的选项),并打印它们而不添加新行(因此它们粘在一起)。请注意,microseconds字段必须预先用0填充,但这不会影响seconds字段,因为它长于6位数字。由此,将微秒转换为毫秒应该是很简单的。

如果你需要一个尾随的新行(也许因为它看起来更好),那么试试

adjtimex | awk '/(time.tv_sec|time.tv_usec):/ { printf("%06d", $2) }' && printf "\n"

还要注意,这需要adjtimexawk可用。如果没有,那么与BusyBox你可以在本地指向他们:

ln -s /bin/busybox ./adjtimex
ln -s /bin/busybox ./awk

然后把上面的称为

./adjtimex | ./awk '/(time.tv_sec|time.tv_usec):/ { printf("%06d", $2) }'

当然,你也可以把它们放在PATH

编辑:

以上这些都适用于我的BusyBox设备。在Ubuntu上,我尝试了同样的事情,并意识到adjtimex有不同的版本。在Ubuntu上,这可以输出以秒为单位的时间,小数位为微秒(包括后面的新行)

sudo apt-get install adjtimex
adjtimex -p | awk '/raw time:/ { print $6 }'

不过我不会在Ubuntu上这么做。我将使用date +%s%N

date命令在OS X上没有提供毫秒,所以使用了python的别名

millis(){  python -c "import time; print(int(time.time()*1000))"; }

alias millis='python -c "import time; print(int(time.time()*1000))"'

编辑:以下来自@CharlesDuffy的评论。 fork任何子进程都需要额外的时间

$ time date +%s%N
1597103627N
date +%s%N  0.00s user 0.00s system 63% cpu 0.006 total

Python仍然在改进它的虚拟机启动时间,并且它不如预先编译的代码(例如date)快。

在我的机器上,它花了大约30ms - 60ms(这是date所采取的6ms的5x-10x)

$ time python -c "import time; print(int(time.time()*1000))"
1597103899460
python -c "import time; print(int(time.time()*1000))"  0.03s user 0.01s system 83% cpu 0.053 total

我认为awkpython更轻,所以awk需要6ms到12ms的范围(即日期的1x到2x):

$ time awk '@load "time"; BEGIN{print int(1000 * gettimeofday())}'
1597103729525
awk '@load "time"; BEGIN{print int(1000 * gettimeofday())}'  0.00s user 0.00s system 74% cpu 0.010 total

我只是想向高山的回答添加我必须做的事情来让这个东西工作:

在Mac上,你需要brew install coreutils,所以我们可以使用gdate。否则在Linux上,它就是date。这个函数将帮助您执行命令,而无需创建临时文件或任何东西:

function timeit() {
start=`gdate +%s%N`
bash -c $1
end=`gdate +%s%N`
runtime=$(((end-start)/1000000000.0))
echo " seconds"
}

你可以将它与字符串一起使用:

timeit 'tsc --noEmit'

下面是一个在Linux上以毫秒为单位获取时间的便携式hack:

#!/bin/sh
read up rest </proc/uptime; t1="${up%.*}${up#*.}"
sleep 3    # your command
read up rest </proc/uptime; t2="${up%.*}${up#*.}"


millisec=$(( 10*(t2-t1) ))
echo $millisec

输出结果为:

3010

这是一个非常廉价的操作,它与shell内部程序和procfs一起工作。

Perl可以用于此目的,甚至在AIX这样的特殊平台上也是如此。例子:

#!/usr/bin/perl -w


use strict;
use Time::HiRes qw(gettimeofday);


my ($t_sec, $usec) = gettimeofday ();
my $msec= int ($usec/1000);


my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
localtime ($t_sec);


printf "%04d-%02d-%02d %02d:%02d:%02d %03d\n",
1900+$year, 1+$mon, $mday, $hour, $min, $sec, $msec;

当你从4.1版本开始使用GNU AWK时,你可以加载时间库并执行以下操作:

$ awk '@load "time"; BEGIN{printf "%.6f", gettimeofday()}'

这将以秒为单位打印自1970-01-01T00:00:00以来的当前时间,精度为亚秒。

< >强the_time = gettimeofday() 返回自1970-01-01 UTC以来以秒为单位流逝的浮点值。如果此平台上时间不可用,则返回-1并设置ERRNO返回的时间应具有亚秒级精度,但实际精度可能会根据平台而有所不同。如果标准的C gettimeofday()系统调用在这个平台上可用,那么它只返回该值。否则,如果在MS-Windows上,它将尝试使用GetSystemTimeAsFileTime().

来源:GNU awk手册

在Linux系统上,标准C函数getimeofday()以微秒精度返回时间。

用时间和时区显示日期

日期+"%d-%m-%Y %T "。% N % Z”

输出:22-04-2020 18:01:35.970289239 IST

纯bash解决方案

bash 5.0 (2019年1月7日发布)开始,你可以使用内置变量EPOCHREALTIME,它包含从纪元开始的秒数,包括小数位精确到微秒(μs) (echo $EPOCHREALTIME打印类似1547624774.371210的东西)。通过删除.和最后三个位置,我们得到毫秒:

要么使用

(( t = ${EPOCHREALTIME/./} / 1000 ))

或者类似的东西

t=${EPOCHREALTIME/./}  # remove the dot (s → µs)
t=${t%???}             # remove the last three digits (µs → ms)

无论哪种方式,t都将是类似1547624774371的东西。

我想从bash生成值,并在Java代码中使用该值转换回日期(Java .util)。

以下命令为我在bash文件中生成值:

date +%s000

打印十进制秒:

start=$(($(date +%s%N)/1000000)) \
&& sleep 2 \
&& end=$(($(date +%s%N)/1000000)) \
&& runtime=$((end - start))


divisor=1000 \
&& foo=$(printf "%s.%s" $(( runtime / divisor )) $(( runtime % divisor ))) \
&& printf "runtime %s\n" $foo # in bash integer cannot cast to float

输出:runtime 2.3