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


286

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


12
date +%s.%N会给你十亿分之一秒,你可以用吗?
2013年

1
@Wrikken虽然不是很可移植。
卡米洛·马丁

16
date +“%Y%m%d。%H%M%S%3N”-通常,我使用此命令获取完整的日期和唯一的时间(直到毫秒),以在UNIX bash脚本中创建临时文件名。如果您的系统无法应付毫秒,则可以分别使用3到6和9进入微秒或纳秒。
Nitin Mahesh

试试date -Ins
Person Person II博士

Answers:


343

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

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

例:

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

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


69
不适用于Mac OS,因为%N不支持date
yegor256

33
问题是要求Linux命令。@alper的答案对于使用GNU coreutils的日期命令很好用。GNUt化您的OSX:在Mac OS X上安装和使用GNU命令行工具
caligari 2014年

77
date +%s%3N更快(基于@ michael-defort的答案)
caligari

10
在OSX上,作为coreutils使用MacPorts或Homebrew的一部分,您需要安装date的GNU版本-然后使用gdate命令。看到这个问题:stackoverflow.com/questions/9804966/...
Pierz

1
尽管日期+%s%3N似乎更容易或更有效,但是在其他偏移量计算中使用它会使时间戳减少了1毫秒!但这种解决方案工作与完善偏移计算
Arsinux

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

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

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

    06:47:42.773

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


32
%xN:字段宽度不错!
fduff 2014年

1
日期+“%Y%m%d。%H%M%S%3N”毫秒。
Nitin Mahesh

4
我认为这是标记为正确答案的更好的答案。
kcondezo

74

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

date +%s%3N

来自man date

%N 纳秒(000000000..999999999)

自1970-01-01 00:00:00 UTC以来的%s

来源:服务器故障的问题如何以Bash来获取当前的Unix时间(以毫秒为单位)?


@Peter Mortensen在我的其中一篇文章中做了他出色的活动读物之一,我感到非常自豪:)谢谢!
fedorqui'SO停止伤害

46

date不支持该%N标志的OS X上,建议coreutils使用Homebrew进行安装。这会给你访问一个名为命令gdate,将表现为date确实在Linux系统上。

brew install coreutils

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

alias date='gdate'

然后执行

$ date +%s%N

10

这是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。


1
到目前为止,只有一个适用于Xeon Phi BusyBox v1.27.0(2017-09-27 13:20:28 EDT)MicroOS的操作系统-很高兴可以投票三次!
加多斯

8

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))"'

2
...但是,一旦完成fork()了一个单独的过程,然后exec编辑了Python解释器,让它加载其库/否则进行初始化,编写其结果并退出,该结果将不再准确。
查尔斯·达菲,

4

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

有问题的系统不支持%Nformat选项,并且没有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


哇,很棒的选择!确实,您的命令有效,但是我不知道为什么。在哪里可以找到awk命令的文档?您如何在地狱中找到如何构建字符串以从adjtimex输出中提取所需信息的方法?
Satria '18

很棒的busybox解决方案
编码

1

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;

1

这样的Python脚本:

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

3
这将不返回毫秒数,这将返回以毫秒表示的秒数。一切都会变成$ SECONDS000
kilianc

1
@kilianc maoyang的Python代码提供了毫秒。
jlliagre

@jlliagre:但是实际时间分辨率是否优于16-17毫秒(1/60秒)?
彼得·莫滕森

是的,Python time.time()至少在macOS上将浮点数返回6个小数位。
porglezomp

1

我只是想添加到 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'

我喜欢这种解决方案,但我对millis更加感兴趣。我将此功能移植到了我在ubuntu中的.bashrc:function timeit () { start=$(date +%s%N); $*; end=$(date +%s%N); runtime=$(((end-start)/1000000)); echo "$runtime ms" }
Uluaiv

1

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

来源:GNU awk手册

在Linux系统上,标准C函数getimeofday()以毫秒为单位返回时间。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.