Getting nanoseconds in a process

A

A. Marin

Hello, I'm trying to get the time:
days:hours:minutes:seconds:nanoseconds in a program in C.
With the instruction date([+FORMAT]) i can get these data, but every
time I call the system it prints out the data. I just want to store
these, ¿how can I do it?

code:

#include<stdlib.h>
#include<sys/stat.h>
#include<time.h>
#include<stdio.h>

int main(void)
{
double d=0,h=0,m=0,s=0,ns=0;
int i=0;

d=system("date +%d");
h=system("date +%H");
m=system("date +%M");
s=system("date +%S");
ns=system("date +%N");

printf("Day: %g",d);
printf("Hour: %g",h);
printf("Minute: %g",m);
printf("Second: %g",s);
printf("Nanosecond: %g",ns);

return 0;
}


Here is the output:

Day: 0 Hour: 0 Minute: 0 Second: 0 Nanosecond: 0

¿What is wrong?

Thanks in advance, A. Marin.
 
I

Ian Collins

A. Marin said:
Hello, I'm trying to get the time:
days:hours:minutes:seconds:nanoseconds in a program in C.
With the instruction date([+FORMAT]) i can get these data, but every
time I call the system it prints out the data. I just want to store
these, ¿how can I do it?

code:

#include<stdlib.h>
#include<sys/stat.h>
#include<time.h>
#include<stdio.h>

int main(void)
{
double d=0,h=0,m=0,s=0,ns=0;
int i=0;

d=system("date +%d");

The return value of system isn't what you expect, check your documentation.
 
K

Keith Thompson

A. Marin said:
Hello, I'm trying to get the time:
days:hours:minutes:seconds:nanoseconds in a program in C.
With the instruction date([+FORMAT]) i can get these data, but every
time I call the system it prints out the data. I just want to store
these, ¿how can I do it?

code:

#include<stdlib.h>
#include<sys/stat.h>

#include<time.h>

You're not using this either -- though perhaps you should be.
#include<stdio.h>

int main(void)
{
double d=0,h=0,m=0,s=0,ns=0;
int i=0;

d=system("date +%d");
h=system("date +%H");
m=system("date +%M");
s=system("date +%S");
ns=system("date +%N");

As Ian pointed out, system() doesn't return what you think it returns.

But even if it did (and it seems unlikely that it would do so by
returning a value of type double), you need to re-think your approach.
I presume from the way you're using them that the "date +%d", "date
+%H" etc. commands print an element of the current date or time.
(Ok, I actualliy know how the "date" command works, but that knowledge
has little to do with C.) You're invoking 5 commands at 5 different
times. Think about what happens if the first call happens just before
midnight, and the second happens just after midnight. Think about
ways to get all the information you need at once, so you don't have
this timing issue.
printf("Day: %g",d);
printf("Hour: %g",h);
printf("Minute: %g",m);
printf("Second: %g",s);
printf("Nanosecond: %g",ns);

return 0;
}


Here is the output:

Day: 0 Hour: 0 Minute: 0 Second: 0 Nanosecond: 0

As expected.

There are ways to get the current time without invoking an external
program. Standard C defines several functions in the <time.h> header,
though none of them are guaranteed to give you nanosecond resolution.
Your system, which is probably something Unix-like, is likely to
provide some system-specific functions that might suit your needs.
Consult your system's documentation, or, failing that, ask in
comp.unix.programmer.
 
K

Kaz Kylheku

You're on Ubuntu Linux, presumably. The date(1) command on your system
is from GNU coreutils. GNU date(1) has a %N extension for nanoseconds
that is implemented by, in order of preference:

nanotime()

I just recursively grepped the entire source tree of glibc-2.9 and there is
no such function in there.

It may be that the build ./configure script for GNU coreutils would like to use
that function, but it's not a POSIX function nor anything Linux-specific.

Autoconf configure scripts do lots of idiotic things---such as, for instance,
fail outright, test for the presence of Fortran compilers when there isn't a
shred of Fortran in the project, or try to compile /and/ run test programs
when it's clearly established that the program is being cross-compiled.

Autoconf is the work of drooling idiots, who should be institutionalized (if
indeed they aren't).

You better not educate yourself about what functions to prefer based
on what some GNU program looks for.
clock_gettime(CLOCK_REALTIME, ...)
gettimeofday() with crappy resolution

If you want nanoseconds, there is no point in using gettimeofday, unless you
have some very old Linux with a glibc that doesn't have clock_gettime.

CLOCK_REALTIME can jump forward and backwards when the date is adjusted (for
instance by an NTP daemon). So the nanosecond precision means nothing, since
the function cannot be depended on to measure the elapsed time between two
real-time events. This unfortunate misuse of the term ``real time'' refers to
calendar time, not to ``real time processing''. To measure the elapsed time
between events, use CLOCK_MONOTONIC (i.e. always increasing clock type,
unaffected by system time adjustments).
 
A

Antoninus Twink

Autoconf configure scripts do lots of idiotic things---such as, for instance,
fail outright, test for the presence of Fortran compilers when there isn't a
shred of Fortran in the project, or try to compile /and/ run test programs
when it's clearly established that the program is being cross-compiled.

Autoconf is the work of drooling idiots, who should be
institutionalized (if indeed they aren't).

You do realize that it's the developer of the program in question who
decides what tests autoconf should perform by choosing what goes in to
his configure.ac file, not the creators of autoconf, don't you?

And if you find a bug in a built-in autoconf feature test macro, why not
file a bug report instead of bitching about it here?
 
F

Falcon Kirtaran

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Kaz said:
I just recursively grepped the entire source tree of glibc-2.9 and there is
no such function in there.

It may be that the build ./configure script for GNU coreutils would like to use
that function, but it's not a POSIX function nor anything Linux-specific.

Autoconf configure scripts do lots of idiotic things---such as, for instance,
fail outright, test for the presence of Fortran compilers when there isn't a
shred of Fortran in the project, or try to compile /and/ run test programs
when it's clearly established that the program is being cross-compiled.

Autoconf is the work of drooling idiots, who should be institutionalized (if
indeed they aren't).

You better not educate yourself about what functions to prefer based
on what some GNU program looks for.


If you want nanoseconds, there is no point in using gettimeofday, unless you
have some very old Linux with a glibc that doesn't have clock_gettime.

CLOCK_REALTIME can jump forward and backwards when the date is adjusted (for
instance by an NTP daemon). So the nanosecond precision means nothing, since
the function cannot be depended on to measure the elapsed time between two
real-time events. This unfortunate misuse of the term ``real time'' refers to
calendar time, not to ``real time processing''. To measure the elapsed time
between events, use CLOCK_MONOTONIC (i.e. always increasing clock type,
unaffected by system time adjustments).

It is far from useless data, though. It makes a wonderful value to use
in srand().

- --
- --Falcon Darkstar Kirtaran
- --
- --OpenPGP: (7902:4457) 9282:A431
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iQIcBAEBAgAGBQJJdf1lAAoJEKmxP9YxEE4rrWkP/AnNUqt43rJCXxNHnA38CAob
mG9WV7tFu6o2dAWS/MABsmwaIhW/5BqTPrkw3fU5Qu4L5SnqOfd+o/bCoDRG+anr
wktrvvB/ALOH5N3mQ7kYS/XRIOnt1YDq9+RUhNM47xqLUDtP3ObdgmHjjnR0GwBp
gB7JkR77ILIw+d2we/iSy4hYURDzX5hpX3y9F5V0LCAew4E8PlYmR71GGLEYCQJa
J7JhTRt7N40mTL49nU28kRDhL0KeqUj7jUjba88iQRG/5vXFbmTSbg8xiLlO1vVk
uL746Vxy1q76KUmrbxQ9/cWTNbNjM9rS2+GhURvFy/0fp2frRfRX4fyd0SitUdQt
75vbLS5yiqido2qMameHo57P90Tv6cyicg9/gZJwZrzY7SI/DCW8XEfnnFF4QkDL
X2d2Utxe0lhjaZg/5ULHH1yV7Ms0rfv6HKIJF+wzZcb3y3EpOs0gSzLjJNiADQ2K
HA9yF/Ici+3asHS2xDyFpYiy46nSTULILp/bA5VwkPMYrzdzJPHOjI5dF725Cua1
0+3ajJlKyU5UgBFO/uuKcyQscq+peTznv/vFx4tK4bFSHQCyMFvb84GL+vrJSxUr
J+sunCZBcuJ8qqgMSO9E4pJJpZNTssyw6Y0geIrQgrFDUiooX1cm5Q/4DaJdVF54
i6zRqdkB1Bsj7I1UStto
=T627
-----END PGP SIGNATURE-----
 
I

Ian Collins

Anthony said:
Try this if your using Linux:
*************************************************
#include <stdio.h>
#include <sys/time.h>

#define SIZE 20

int main(int argc, char *argv[]) {
struct timeval timevals[SIZE];
int index;

/* Read the clock as fast as possible: */
for (index = 0; index < SIZE; index++) {
gettimeofday(&timevals[index], (struct timezone *)0);

Why the cast for a void* parameter?
}

/* Print out the results */
for (index = 0; index < SIZE; index++) {
printf("[%d]: %d.%d\n", index, (int) timevals[index].tv_sec, (int)
timevals[index].tv_usec);

Again, why cast?
 
K

Keith Thompson

Anthony Fremont said:
BTW, there is also a timespec struct defined in time.h, it uses nanosecond
resolution. I'm not sure what function you could call that would return a
real value though, but there are macros that convert between timeval and
timespec structure formats. This is done by multiplying uS by 1000 or
dividing nS by 1000 which would obviously not increase precision at all.

No, there's no timespec struct in time.h specified by the C standard.
That appears to be a POSIX extension.
 
I

Ian Collins

Anthony said:
Ian said:
Anthony said:
Try this if your using Linux:
*************************************************
#include <stdio.h>
#include <sys/time.h>

#define SIZE 20

int main(int argc, char *argv[]) {
struct timeval timevals[SIZE];
int index;

/* Read the clock as fast as possible: */
for (index = 0; index < SIZE; index++) {
gettimeofday(&timevals[index], (struct timezone *)0);
Why the cast for a void* parameter?

Because it's my pen and documents what the function expects. Is there some
obtuse corner-case where it will cause a problem?

The man page documents what the function expects, the code documents
what it gets!
}

/* Print out the results */
for (index = 0; index < SIZE; index++) {
printf("[%d]: %d.%d\n", index, (int) timevals[index].tv_sec,
(int) timevals[index].tv_usec);
Again, why cast?

To eliminate the warnings.
Then use the correct conversion specification.
 
N

Nate Eldredge

Ian Collins said:
Anthony said:
}

/* Print out the results */
for (index = 0; index < SIZE; index++) {
printf("[%d]: %d.%d\n", index, (int) timevals[index].tv_sec,
(int) timevals[index].tv_usec);
Again, why cast?

To eliminate the warnings.
Then use the correct conversion specification.

The types of the `tv_sec' and `tv_usec' members of `struct timeval' are
`time_t' and `suseconds_t' respectively. What conversion specifiers do
you recommend?
 
I

Ian Collins

Nate said:
Ian Collins said:
Anthony said:
}

/* Print out the results */
for (index = 0; index < SIZE; index++) {
printf("[%d]: %d.%d\n", index, (int) timevals[index].tv_sec,
(int) timevals[index].tv_usec);
Again, why cast?
To eliminate the warnings.
Then use the correct conversion specification.

The types of the `tv_sec' and `tv_usec' members of `struct timeval' are
`time_t' and `suseconds_t' respectively. What conversion specifiers do
you recommend?

%ld.
 
N

Nate Eldredge

Ian Collins said:
Nate said:
Ian Collins said:
Anthony Fremont wrote:
}

/* Print out the results */
for (index = 0; index < SIZE; index++) {
printf("[%d]: %d.%d\n", index, (int) timevals[index].tv_sec,
(int) timevals[index].tv_usec);
Again, why cast?
To eliminate the warnings.

Then use the correct conversion specification.

The types of the `tv_sec' and `tv_usec' members of `struct timeval' are
`time_t' and `suseconds_t' respectively. What conversion specifiers do
you recommend?

%ld.

How do you know that those types are (promoted to) `long int'?
 
N

Nate Eldredge

Anthony Fremont said:
Ian said:
Anthony said:
Ian Collins wrote:
Anthony Fremont wrote:
}

/* Print out the results */
for (index = 0; index < SIZE; index++) {
printf("[%d]: %d.%d\n", index, (int)
timevals[index].tv_sec, (int) timevals[index].tv_usec);
Again, why cast?

To eliminate the warnings.
Then use the correct conversion specification.

Could you tell me the proper specifier for time_t please? I never said my
program was perfect, I only said it worked on Linux. I figure if all you
can find wrong is some unnecessary harmless casting then I'm cool with that.
I should have used unsigned int though.

There isn't really one. time_t is guaranteed to be "an arithmetic type
capable of representing seconds"; other than that you don't know how big
it is, or AFAIK even whether it is integer or floating point. Your code
will invoke undefined behavior if the value doesn't fit in an `int'; at
the very least it would print out a bogus value.

On my machine, time_t is `int64_t', and in about 30 years from now, its
value will not fit in an `int'.

Portably, the way to deal with `time_t' is to pass it to `localtime' or
`gmtime' to extract the date and time. You can also use `ctime' to
convert it to a standard string representation.

The tv_usec field should be a signed integral type (according to the
Single Unix Spec), so you should be able to safely cast it to `intmax_t'
and print it with `%jd'.
 
D

Default User

There isn't really one. time_t is guaranteed to be "an arithmetic
type capable of representing seconds";

Not even that. It's capable of representing times.




Brian
 
I

Ian Collins

Nate said:
Ian Collins said:
Nate said:
Anthony Fremont wrote:
}

/* Print out the results */
for (index = 0; index < SIZE; index++) {
printf("[%d]: %d.%d\n", index, (int) timevals[index].tv_sec,
(int) timevals[index].tv_usec);
Again, why cast?
To eliminate the warnings.

Then use the correct conversion specification.
The types of the `tv_sec' and `tv_usec' members of `struct timeval' are
`time_t' and `suseconds_t' respectively. What conversion specifiers do
you recommend?
%ld.

How do you know that those types are (promoted to) `long int'?

How do you know their value will fit in an int?
 
N

Nate Eldredge

Default User said:
Not even that. It's capable of representing times.

That's all that ISO C guarantees, true. The OP got the time_t by
calling gettimeofday(), which is a Unix function, and Unix (e.g. in the
SUS) guarantees that it represents seconds since the Epoch. But in both
cases, my point is that it's hard to make use of it directly, and the
right thing to do is to use the standard functions provided for that
purpose.
 
N

Nate Eldredge

Ian Collins said:
Nate said:
Ian Collins said:
Nate Eldredge wrote:

Anthony Fremont wrote:
}

/* Print out the results */
for (index = 0; index < SIZE; index++) {
printf("[%d]: %d.%d\n", index, (int) timevals[index].tv_sec,
(int) timevals[index].tv_usec);
Again, why cast?
To eliminate the warnings.

Then use the correct conversion specification.
The types of the `tv_sec' and `tv_usec' members of `struct timeval' are
`time_t' and `suseconds_t' respectively. What conversion specifiers do
you recommend?
%ld.

How do you know that those types are (promoted to) `long int'?

How do you know their value will fit in an int?

You don't; I pointed out in another post that the given code is
incorrect. But you can't avoid a cast by using a "correct" conversion
specifier, since there isn't one that will always work. Nor will a cast
suffice, because AFAICT there isn't a single type that you can safely
cast a time_t into.

I think the following *might* be safe.

#include <stdint.h>
#include <stdio.h>

void print_time_t(time_t t) {
time_t half = 0.5, minusone = -1;
if (half > 0.4 && half < 0.6) /* floating point */
printf("%Lf", (long double)t);
else if (minusone < 0) /* signed integer */
printf("%jd", (intmax_t)t);
else
printf("%ju", (uintmax_t)t);
}

Of course, in any case the output is implementation-dependent and not
necessarily useful in general.
 
C

CBFalconer

Anthony said:
BTW, there is also a timespec struct defined in time.h, it uses
nanosecond resolution. I'm not sure what function you could call
that would return a real value though, but there are macros that
convert between timeval and timespec structure formats. This is
done by multiplying uS by 1000 or dividing nS by 1000 which would
obviously not increase precision at all.

The word 'timespec' does not appear in the C standard. Thus no
such thing exists in the standard C language, and intimating that
it does is a pure falsity.
 
I

Ian Collins

Nate said:
You don't; I pointed out in another post that the given code is
incorrect. But you can't avoid a cast by using a "correct" conversion
specifier, since there isn't one that will always work. Nor will a cast
suffice, because AFAICT there isn't a single type that you can safely
cast a time_t into.

Fair enough, I was cheating by looking at my system's headers. Casting
to the system's largest int type should be safe enough.

I guess I'm too used to C++ where the compiler takes care of these nasties!
 
C

CBFalconer

Ian said:
Nate said:
Ian Collins said:
Anthony Fremont wrote:

/* Print out the results */
for (index = 0; index < SIZE; index++) {
printf("[%d]: %d.%d\n", index,
(int) timevals[index].tv_sec,
(int) timevals[index].tv_usec);

Again, why cast?

To eliminate the warnings.

Then use the correct conversion specification.

The types of the `tv_sec' and `tv_usec' members of `struct
timeval' are`time_t' and `suseconds_t' respectively. What
conversion specifiers do you recommend?

%ld.

I see no specification for time_t, other than arithmetic type, so
that conversion is probably accurate. However, there is no
specification whatsoever for suseconds_t.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top