11

I want to know current system time with microsecond Resolution. date +%s returns Time in seconds since epoch(1-1-1970). How can I get time in microseconds Resolution. How much delay is in querying this value? By delay I mean suppose at time t secs i query and it gives me value t + t' what is t' ?
My Use case: I am recording Videos using multiple Raspberry Pis simulatenously. Now I want to timestamp each frame of videos so that I can align them. Currently for timestamp it's using boot time(time since boot). Boot time is accurate but it's different for each Raspberry Pi. I have configured all Pi's to a NTP Server thus all have same System time. So basically I want the timestamp of System time not Boot Time. How can I do that ?

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
Coderaemon
  • 219
  • 1
  • 2
  • 6
  • 3
    do you mean microsecond *resolution*? – Skaperen May 21 '15 at 10:47
  • 2
    Please clarify what you mean by delay. Monitors usually don't update their display more than a few dozen times per second. Your brain will take several hundredth of seconds to process the image it sees on the screen, so in any case, if that time is just for display and not for comparison with another time, sub-second resolution is mostly meaningless. – Stéphane Chazelas May 21 '15 at 12:37
  • 2
    [What are you trying to achieve?](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – l0b0 May 21 '15 at 13:14
  • 2
    Assuming that your computer sets its time using [NTP](http://en.wikipedia.org/wiki/Network_Time_Protocol), the _accuracy_ of your system time is at best on the order of 10 milliseconds. If you want better than that you'll need a more direct connection to an atomic clock or three. – PM 2Ring May 21 '15 at 13:38
  • 2
    What language? The system calls are `clock_gettime()` and `gettimeofday()`, though in recent Linux that can be [via vdso](http://man7.org/linux/man-pages/man7/vdso.7.html) – Stéphane Chazelas May 21 '15 at 14:40
  • Can you record some sort of reference frame at the start of all the videos? Problem is that while you can (at least on Intel processors) get elapsed time down to a clock cycle (with the RDTSC instructions), there's no way that I know of to synchronize two machines much closer than NTP without some specialized hardware. – jamesqf May 21 '15 at 18:37
  • @jamesqf Overkill for most, but it does exist. [PTP (Precision Time Protocol)](https://en.wikipedia.org/wiki/Precision_Time_Protocol) – Phizes May 21 '15 at 22:11
  • What do you mean by “Currently for timestamp it's using boot time”? What difference do you make between “System time” and “Boot Time”? – Gilles 'SO- stop being evil' May 21 '15 at 23:13
  • @PM2Ring NTP can actually do quite a bit better than that. <1ms sync on a LAN is pretty much expected with today's hardware, and the same is possible over the internet if your connection is good and your upstream hosts are chosen well. – hobbs May 22 '15 at 19:42
  • @Gilles Boot Time is the time since the Pi has booted(every restart sets it to zero). System time is the time set by NTP server – Coderaemon May 23 '15 at 05:44
  • @Coderaemon But according to what clock? The only difference between time since boot and system time is an offset that doesn't change, and time since boot can only be calculated by taking the difference between system time and recorded boot time. Unless you're using a different clock to record video timestamps, in which case, how are you getting these clock values? (And why not system time everywhere?) – Gilles 'SO- stop being evil' May 23 '15 at 09:55
  • @hobbs: Ok, but some of us don't have much choice of upstream hosts. :) FWIW, I wrote that comment in response to the OP's original question, which only consisted of the 1st paragraph where they were wanting to get µs accuracy of epoch time; I was just pointing out that that's not easy. But now we know what the OP's actually trying to do it's clear they don't need epoch time to that accuracy, and having an NTP server on the local LAN is more than adequate for the task. – PM 2Ring May 23 '15 at 14:54

5 Answers5

15
date +%s%N

will give the nano seconds since epoch To get the micro seconds just do an eval

expr `date +%s%N` / 1000
amisax
  • 2,957
  • 17
  • 23
  • How much delay is there for this query ? – Coderaemon May 21 '15 at 11:49
  • 3
    @Coderaemon Probably in the order of milliseconds (or more) since it has to launch a new process, read its output and compute something. – Bakuriu May 21 '15 at 12:23
  • 1
    Note that's GNU specific. `date +%s%6N` for microseconds. – Stéphane Chazelas May 21 '15 at 12:39
  • @Bakuriu if `date` is in cache and doesn't have to be loaded from disk, none of those things will take milliseconds plural on modern hardware. On my machine running `expr \`date +%s%N\` / 1000 ; expr \`date +%s%N\` / 1000` gives two timestamps on average 950us apart. – hobbs May 22 '15 at 19:47
  • @Bakuriu a C version that calls `gettimeofday` and does no math gives times about 410us apart when called twice in the same way, which gives some idea where the overhead is (probably mostly forking and libc startup). – hobbs May 22 '15 at 19:55
9

There's no much point asking for this kind of precision in a shell script, given that running any command (even the date command) will take at least a few hundreds of those microseconds.

In particular, you can't really use the date command to time the execution of a command with this kind of precision.

For that, best would be to use the time command or keyword.

A few implementations allow changing the format to give you the elapsed time only with subsecond precision.

$ bash -c 'TIMEFORMAT=%3R; time date +%s'
1432210052
0.001

$ ksh -c 'TIMEFORMAT=%3R; time date +%s'
1432210094
0.001

$ zsh -c 'TIMEFMT=%*E; time date +%s'
1432210123
0.001

Various shells have various builtin (so with minimal delay) ways to get you the time:

ksh93 and zsh have a $SECONDS variable that will give you subsecond precision if you change its type to float:

$ zsh -c 'typeset -F SECONDS=0; date; echo "$SECONDS"'
Thu 21 May 13:09:37 BST 2015
0.0012110000
$ ksh -c 'typeset -F SECONDS=0; date; echo "$SECONDS"'
Thu 21 May 13:09:42 BST 2015
0.0010249615

zsh has a $EPOCHREALTIME special variable (available in the zsh/datetime module):

$ zsh -c 'zmodload zsh/datetime; echo $EPOCHREALTIME; date; echo $EPOCHREALTIME'
1432210318.7319943905
Thu 21 May 13:11:58 BST 2015
1432210318.7333047390

ksh93 and newer versions of bash support the %(format)T format in their printf builtin, however bash doesn't support %N (even though that's a GNU extension), and they disagree on how to express now.

$ ksh -c 'printf "%(%s.%N)T\n" now;printf "%(%s.%N)T\n" now'
1432210726.203840000
1432210726.204068000

(as you can see, 228 of those microseconds still elapsed between the two invocations of that builtin command).

Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
  • 1
    I can also use python(in a .py file) to get that but `time.time()` also has some delay? Using bash woulbe be most accurate? – Coderaemon May 21 '15 at 12:22
  • 1
    @Coderaemon, delay between what and what? Between you pressing enter and the displayed date reaching your retina? You know pressing enter will take several thousand microseconds right? – Stéphane Chazelas May 21 '15 at 12:28
  • suppose time is `t` secs when i query and it gives me value `t + t'` what is `t'` ? – Coderaemon May 21 '15 at 12:30
  • 2
    @Coderaemon: Maybe you should explain (in the body of your question) what you're _really_ trying to do. Otherwise, we're bound to head into [XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) territory. – PM 2Ring May 21 '15 at 12:55
  • 2
    @Coderaemon What do you consider being the _querying time_? When you press enter after having entered that hypothetical command, or when the signal from the keyboard reaches the USB controller, or when the X server reads that from the input device, or when it generates the keypress event, or when your terminal emulator processes that event or when it writes the corresponding CR character to the tty device, or when your shell reads that command from the tty device, or when the shell spawns the process to execute the command... – Stéphane Chazelas May 21 '15 at 13:00
  • The absolute time according to system clock when the frame(check edited question body) was captured – Coderaemon May 21 '15 at 13:53
5

As you said date +%s returns the number of seconds since the epoch. So,

date +%s%N returns the seconds and the current nanoseconds.

Dividing date +%s%N the value by 1000 will give in microseconds.i.e

echo $(($(date +%s%N)/1000))

Thushi
  • 9,388
  • 4
  • 29
  • 43
2

If you have configured all of the Raspberry Pis to a local NTP Server, i.e. you've set up an NTP Server on your LAN, then their synchronization should be adequate for your video frame timestamping task.

Both Bash and Python need to make a system function call to retrieve the system time. There's no advantage in using Bash to make that call. Both Python & Bash script are interpreted languages and the time overheads involved in executing scripts will generally be greater than with a compiled language, OTOH, Python scripts are compiled to Python bytecode before execution which generally makes them more efficient than Bash scripts, which do not have any form of compilation. And in this particular case of video frame timestamping, a script written in Python is bound to be far more precise than one written in Bash.

However, when doing stuff like this on a multitasking OS you will get various unpredictable delays due to the fact that your CPU is switching between running your job and handling a bunch of other tasks. So do your best to minimize those other tasks and run the timestamping script at a high priority to reduce the impact of those other tasks. Note that making a system call to get the time while the kernel is in the middle of reading from or writing to the HD is probably not a good idea. :)

If you're doing your timestamp stuff in a tight loop you can track the time difference between each timestamp. And if that difference gets too high, or varies too much, your script can decide that the current timestamps may be inadequate. OTOH, assuming your framerate is 50 frames/second, that's 20 milliseconds / frame, so millisecond precision is probably more than adequate for this task.

FWIW, here's a little bit of Python running on my 2GHz machine at normal priority with a typical task load (including downloading & playing music with VLC).

>>> from time import time as tf
>>> t=[tf()for _ in range(9)];['%0.3f'%(1E6*(u-v))for u,v in zip(t[1:],t)]
['2.146', '0.954', '1.907', '1.192', '1.907', '1.907', '1.192', '0.954']

As you can see, the variation at the microsecond level isn't too bad.

PM 2Ring
  • 6,553
  • 2
  • 27
  • 32
0

You don't need microseconds resolution, milliseconds will do for about 20 to 60 frames per second.

If you you get system time for all Pis from a NTP Server one time, they will be missaligned after some time again, because each internal clock may have an individual error of about 100 ppm (part per million). After 200 seconds you might have a difference of up to 20 ms.

I doubt that all Pis will be aligned with sub milliseconds precision just after they got the time from the NTP server.

Of course the frame rate of each Pi will have an individual error of about 100 ppm too.

I would think of a central clock source for all Pis.

Good luck, you will need it.

Uwe
  • 1
  • 1
    If I look at various NTP clients in my (wireless) network, it looks like they don't drift more than 5ms (abs(offset)+abs(jitter)). With a cluster wired through a switch, it should be better than that, which is plenty of precision for 60fps. (note: I feed my network off a stratum 2 server, but I actually don't think that'll make a huge difference if everyone goes off the same server; of course, making a s1 server is trivial these days with $25 in parts on an existing pi) – cdegroot Sep 07 '16 at 00:43