378

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

4

15 回答 15

454
  • date +"%T.%N"以纳秒返回当前时间。

    06:46:41.431857000
    
  • date +"%T.%6N"返回当前时间,纳秒四舍五入到前 6 位,即微秒。

    06:47:07.183172
    
  • date +"%T.%3N"返回当前时间,纳秒四舍五入到前 3 位,即毫秒。

    06:47:42.773
    

通常,date命令格式的每个字段都可以指定一个可选的字段宽度。

于 2013-09-09T17:55:07.910 回答
423

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

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

例子:

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

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

于 2013-05-14T17:00:41.217 回答
102

纳米是 10 -9和毫 10 -3。因此,我们可以使用纳秒的前三个字符来获取毫秒:

date +%s%3N

来自man date

%N 纳秒 (000000000..999999999)

自 1970 年 1 月 1 日 00:00:00 UTC 以来的 %s秒

资料来源:Server Fault 的如何在 Bash 中获取当前的 Unix 时间(以毫秒为单位)?.

于 2015-06-24T07:49:39.077 回答
70

date不支持该%N标志的 OS X 上,我建议coreutils使用Homebrew安装。这将使您可以访问一个名为的命令,该命令gdate的行为与dateLinux 系统上的行为相同。

brew install coreutils

为了获得更“原生”的体验,您可以随时将其添加到您的.bash_aliases

alias date='gdate'

然后执行

$ date +%s%N
于 2015-11-10T23:21:37.660 回答
21

这是一个以毫秒为单位获取时间的 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。

于 2018-02-13T10:53:32.417 回答
10

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 的评论。分叉任何子进程需要额外的时间。

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

Python 仍在改进它的 VM 启动时间,它的速度不如提前编译的代码(例如date)。

在我的机器上,大约需要 30 毫秒 - 60 毫秒(即 6 毫秒的 5x-10 倍date

$ 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

我认为awk比 轻量级python,因此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
于 2016-10-16T07:29:43.247 回答
7

在大多数情况下,其他答案可能就足够了,但当我在BusyBox系统上遇到问题时,我想我会加两分钱。

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

经过多次挠头,我们(感谢戴夫!)想出了这个:

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

adjtimex它从(通常用于设置系统时钟的选项)的输出中提取秒和微秒,并在没有新行的情况下打印它们(因此它们粘在一起)。请注意,微秒字段必须预先填充零,但这不会影响超过六位数的秒字段。由此,将微秒转换为毫秒应该是微不足道的。

如果您需要一个尾随的新行(可能是因为它看起来更好),然后尝试

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

另请注意,这需要adjtimex并且awk可用。如果没有,那么使用 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

于 2016-08-10T11:32:51.143 回答
6

纯 bash 解决方案

bash5.0(2019 年 1 月 7 日发布)开始,您可以使用包含自纪元以来的秒数的内置变量EPOCHREALTIME,包括小数位到微秒 (μs) 精度(echo $EPOCHREALTIME打印类似1547624774.371215)。通过删除.最后三个位置,我们得到毫秒:

要么使用

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

或类似的东西

t=${EPOCHREALTIME/./}
t=${t%???}

无论哪种方式t都会像1547624774371.

于 2021-04-11T11:53:20.050 回答
6

显示带有时间和时区的日期

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

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

于 2020-04-22T12:33:06.293 回答
3

我只是想在Alper 的回答中添加我必须做的事情才能使这些东西正常工作:

在 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'
于 2017-05-15T18:47:59.143 回答
2

像这样的 Python 脚本:

import time
cur_time = int(time.time()*1000)
于 2015-06-23T22:09:27.720 回答
2

当您从 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返回的时间应该有亚秒精度,但实际精度可能因平台而异。如果标准 Cgettimeofday()系统调用在该平台上可用,则它只返回值。否则,如果在 MS-Windows 上,它会尝试使用GetSystemTimeAsFileTime().

来源:GNU awk 手册

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

于 2019-11-18T13:24:25.710 回答
2

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

以下命令适用于我在 bash 文件中生成值:

date +%s000

于 2021-06-29T12:29:13.427 回答
2

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;
于 2018-11-28T11:20:45.460 回答
0

打印小数秒:

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

于 2021-12-21T12:47:39.000 回答