Printing Current Time in Milliseconds or Nanoseconds with Printf Builtin

Printing current time in milliseconds or nanoseconds with printf builtin

In bash 5, you can get microsecond precision from EPOCHREALTIME. However, printf itself has no way to access that directly, so you need to extract the microseconds yourself.

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

This takes a little time, but the result appears to be accurate to about 0.05 milliseconds.

Command to get time in milliseconds

date +%s%N returns the number of seconds + current nanoseconds.

Therefore, echo $(($(date +%s%N)/1000000)) is what you need.

Example:

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

date +%s returns the number of seconds since the epoch, if that's useful.

How to print current time (with milliseconds) using C++ / C++11

You can use Boost's Posix Time.

You can use boost::posix_time::microsec_clock::local_time() to get current time from microseconds-resolution clock:

boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();

Then you can compute time offset in current day (since your duration output is in the form <hours>:<minutes>:<seconds>.<milliseconds>, I'm assuming they are calculated as current day offset; if they are not, feel free to use another starting point for duration/time interval):

boost::posix_time::time_duration td = now.time_of_day();

Then you can use .hours(), .minutes(), .seconds() accessors to get the corresponding values.

Unfortunately, there doesn't seem to be a .milliseconds() accessor, but there is a .total_milliseconds() one; so you can do a little subtraction math to get the remaining milliseconds to be formatted in the string.

Then you can use sprintf() (or sprintf()_s if you are interested in non-portable VC++-only code) to format those fields into a raw char buffer, and safely wrap this raw C string buffer into a robust convenient std::string instance.

See the commented code below for further details.

Output in console is something like:

11:43:52.276


Sample code:

///////////////////////////////////////////////////////////////////////////////

#include <stdio.h> // for sprintf()

#include <iostream> // for console output
#include <string> // for std::string

#include <boost/date_time/posix_time/posix_time.hpp>


//-----------------------------------------------------------------------------
// Format current time (calculated as an offset in current day) in this form:
//
// "hh:mm:ss.SSS" (where "SSS" are milliseconds)
//-----------------------------------------------------------------------------
std::string now_str()
{
// Get current time from the clock, using microseconds resolution
const boost::posix_time::ptime now =
boost::posix_time::microsec_clock::local_time();

// Get the time offset in current day
const boost::posix_time::time_duration td = now.time_of_day();

//
// Extract hours, minutes, seconds and milliseconds.
//
// Since there is no direct accessor ".milliseconds()",
// milliseconds are computed _by difference_ between total milliseconds
// (for which there is an accessor), and the hours/minutes/seconds
// values previously fetched.
//
const long hours = td.hours();
const long minutes = td.minutes();
const long seconds = td.seconds();
const long milliseconds = td.total_milliseconds() -
((hours * 3600 + minutes * 60 + seconds) * 1000);

//
// Format like this:
//
// hh:mm:ss.SSS
//
// e.g. 02:15:40:321
//
// ^ ^
// | |
// 123456789*12
// ---------10- --> 12 chars + \0 --> 13 chars should suffice
//
//
char buf[40];
sprintf(buf, "%02ld:%02ld:%02ld.%03ld",
hours, minutes, seconds, milliseconds);

return buf;
}

int main()
{
std::cout << now_str() << '\n';
}

///////////////////////////////////////////////////////////////////////////////

time() and gettimeofday() return different seconds

Both calls are implemented as kernel syscalls. Both functions end up reading a struct timekeeper, both refer to the very same instance. But they differ in what they do with it:

time():

uses the get_seconds() function, which is a shortcut to this:

struct timekeeper *tk = &timekeeper;
return tk->xtime_sec;

it just returns xktime_sec.

gettimeofday():

gettimeofday() on the other hand uses do_gettimeofday() (via getnstimeofday) which reads both fields xktime_sec as well as xktime_nsec (via timekeeping_get_ns). Here it might happen that xktime_nsec holds more nanoseconds than a second. This potential extra time is used to increase the tv_sec field by calling the function timespec_add_ns() which does this:

a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns);
a->tv_nsec = ns;

So, tv_sec might get bigger than the xktime_sec field was. And there you have it: a little difference in what time() gives you and what gettimeofday() gives you.

I fought against this issue in fluxbox today and until a better solution occurs I live with this:

uint64_t t_usec = gettimeofday_in_usecs(); // calcs usecs since epoch
time_t t = static_cast<time_t>(t_usec / 1000000L);

Get Formatted Date From Timestamp With Rounded Milliseconds Bash Shell Script

You may simply use %3N to truncate the nanoseconds to the 3 most significant digits:

$ date +"%Y-%m-%d %H:%M:%S,%3N"
2014-01-08 16:00:12,746

or

$ date +"%F %T,%3N"
2014-01-08 16:00:12,746

testet with »GNU bash, Version 4.2.25(1)-release (i686-pc-linux-gnu)«

But be aware, that %N may not implemented depending on your target system or bash version.
Tested on an embedded system »GNU bash, version 4.2.37(2)-release (arm-buildroot-linux-gnueabi)« there was no %N:

date +"%F %T,%N"
2014-01-08 16:44:47,%N

Printing command line arguments in quoted form

1. Using parameter expansion:

You could try inline:

$ set -- 'foo bar' baz
$ echo ${@@Q}
'Foo bar' 'baz'

$ echo ${@@A}
set -- 'Foo bar' 'baz'

$ DOLLAR_AT="'one two' three"
$ echo ${DOLLAR_AT@Q}
''\''one two'\'' three'

$ echo ${DOLLAR_AT@A}
DOLLAR_AT=''\''one two'\'' three'

More info in bash's manpage, under Parameter Expansion subsection.

   ${parameter@operator}
Parameter transformation. The expansion is either a transforma‐
tion of the value of parameter or information about parameter
itself, depending on the value of operator. Each operator is a
single letter:
...
Q The expansion is a string that is the value of parameter
quoted in a format that can be reused as input.
...
A The expansion is a string in the form of an assignment
statement or declare command that, if evaluated, will
recreate parameter with its attributes and value.

For re-using this:

$ myString1=${@@Q}
$ set -- something\ else
$ . <(echo "set -- $myString1")
$ echo ${@@A}
set -- 'Foo bar' 'baz'

1.1. Difference between $* and $@.

Simply $* is used to generate strings where $@ could generate both arrays or stringS, depending on context.

From bash's manpage:

   *      Expands to the positional parameters, starting from  one...
... That is, "$*" is equivalent to "$1c$2c...", where c is
the first character of the value of the IFS variable...
   @      Expands to the positional parameters,  starting  from  one...
... That is, "$@" is equivalent to "$1" "$2" ...

Small demo:

$ paramExpDemo() {
local IFS=+ _arry
_arry="${@@Q}" # var="..." -> context string
declare -p _arry

_arry="${*@Q}"
declare -p _arry

_arry=("${@@Q}") # var=(...) -> context array
declare -p _arry

_arry=("${*@Q}")
declare -p _arry
}

then

$ paramExpDemo  'foo bar' baz
declare -- _arry="'foo bar'+'baz'"
declare -- _arry="'foo bar'+'baz'"
declare -a _arry=([0]="'foo bar'" [1]="'baz'")
declare -a _arry=([0]="'foo bar'+'baz'")

In context string, $@ and $* will give same result, but in context array, $* will return a string when $@ return an array.

$ set -- 'foo bar' baz
$ Array=("${@@Q}")
$ declare -p Array
declare -a Array=([0]="'foo bar'" [1]="'baz'")
$ echo "${Array[@]@Q}"
''\''foo bar'\''' ''\''baz'\'''

2. Using printf %q

As Léa Gris rightly commented out, you could use:

$ printf '%q\n' "$@"
Foo\ bar
baz

$ printf -v myString2 "%q " "$@"
$ echo "${myString2% }"
Foo\ bar baz

For re-using this:

$ set -- something\ else
$ . <(echo "set -- $myString2")
$ echo ${@@A}
set -- 'Foo bar' 'baz'

Note: As Charles Duffy commented out,this is not perfect! In fact, there is no way to retrieve which syntax was used in command line.

$ printf "<%q>\n" "$myString1" "${myString2% }"
<\'Foo\ bar\'\ \'baz\'>
<Foo\\\ bar\ baz>

As both string work for sourcing variable, they are not same, so further string manipulation could become complex...

Most idiomatic way to print a time difference in Java?

Apache Commons has the DurationFormatUtils class for applying a specified format to a time duration. So, something like:

long time = System.currentTimeMillis();
//do something that takes some time...
long completedIn = System.currentTimeMillis() - time;

DurationFormatUtils.formatDuration(completedIn, "HH:mm:ss:SS");

Linux C++ time measurement library, fast printing library

To get a time in nanoseconds, use clock_gettime(). To measure an elapsed time taken by the code, CLOCK_MONOTONIC_RAW clock type must be used. Using other clock types is not really a solution because they are subject to NTP adjustments.

As for the printing part - define slow. A "general" code to convert built-in data types into ASCII strings is always slow. There is also a buffering going on (which is good in most cases). If you can make some good assumptions about your data, you can always throw in your own conversion to ASCII which will beat a general-purpose solutions, and make it faster.

EDIT:

See also an example of using clock_gettime() function and OS X specific mach_absolute_time() functions here:

  • stopwatch.h
  • stopwatch.c
  • stopwatch_example.c

Custom format for time command

You could use the date command to get the current time before and after performing the work to be timed and calculate the difference like this:

#!/bin/bash

# Get time as a UNIX timestamp (seconds elapsed since Jan 1, 1970 0:00 UTC)
T="$(date +%s)"

# Do some work here
sleep 2

T="$(($(date +%s)-T))"
echo "Time in seconds: ${T}"

printf "Pretty format: %02d:%02d:%02d:%02d\n" "$((T/86400))" "$((T/3600%24))" "$((T/60%60))" "$((T%60))""

Notes:
$((...)) can be used for basic arithmetic in bash – caution: do not put spaces before a minus - as this might be interpreted as a command-line option.

See also: http://tldp.org/LDP/abs/html/arithexp.html

EDIT:

Additionally, you may want to take a look at sed to search and extract substrings from the output generated by time.

EDIT:

Example for timing with milliseconds (actually nanoseconds but truncated to milliseconds here). Your version of date has to support the %N format and bash should support large numbers.

# UNIX timestamp concatenated with nanoseconds
T="$(date +%s%N)"

# Do some work here
sleep 2

# Time interval in nanoseconds
T="$(($(date +%s%N)-T))"
# Seconds
S="$((T/1000000000))"
# Milliseconds
M="$((T/1000000))"

echo "Time in nanoseconds: ${T}"
printf "Pretty format: %02d:%02d:%02d:%02d.%03d\n" "$((S/86400))" "$((S/3600%24))" "$((S/60%60))" "$((S%60))" "${M}"

DISCLAIMER:

My original version said

M="$((T%1000000000/1000000))"

but this was edited out because it apparently did not work for some people whereas the new version reportedly did. I did not approve of this because I think that you have to use the remainder only but was outvoted.

Choose whatever fits you.



Related Topics



Leave a reply



Submit