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
Syntax With Pound and Percent Sign After Shell Parameter Name
Clear a Terminal Screen For Real
How to Call a Function (Defined in Shell Script) in a Perl Script
Accessing Shell Variable in a Perl Program
What Is the Use of "Echo || True"
Comparing Variables with Strings Bash
Force Cmake to Use the Full Library Path
What Is the Most Efficient and Elegant Way Develop/Debug Linux Kernel
Awk and Special Brackets Delimiters
Importerror: No Module Named Matplotlib with Matplotlib Installed
How to Write Shell Command Within Pharo Smalltalk
Where Are Ioctl Parameters (Such as 0X1268/Blksszget) Actually Specified
Strange File Permission in Docker Container (Question Marks on Permission Bit and User Bit)
Execve Shellcode Linux Segmentation Fault
How to Get Time Since File Was Last Modified in Seconds with Bash