# Coercing timespec to time_t



## havic (Jan 9, 2004)

In a project I'm currently working on, I stat a file and use time functions.  The stat structure requires that I use timespec structs for my time related file statistics, but I also need to use the current date to find out how long ago the file was created.

I can use the function time(struct time_t timeStruct) to put the current date into timeStruct, which is fine, however I cannot subtract a time_t from a timespec, so I must pass a timespec struct as the arg for time.  This hasn't actually given me any trouble so far, but the compiler warns me against "passing args from incompatible pointer types", and I try to release finished programs with absolutely no warnings or problems anywhere.

Could someone show me how to rid my program of this error?  I get it often enough in other programs as well, so it would be nice to know how to fix it.

EDIT:  I should probably mention that I'm writing this tool in C as well


----------



## rhg (Jan 13, 2004)

Wait a minute...

time_t is not a structure, it is an integer holding the number of seconds since the begin of the "epoch" (which is January 1, 1970, 0:00:00 UTC).

struct tm is a structure and contains the elements tm_year, tm_mon, tm_mday, tm_hour and so on.

// Get the current time
time_t now = time(NULL);

// Convert a time_t into a struct tm using your current time zone
struct tm *ptm = localtime(&now);

// Convert a time_t into a struct tm using UTC
struct tm *ptm = gmtime(&now);

// Convert a struct tm into a time_t
struct tm tm;
tm.tm_year = 104; // 2004
tm.tm_month = 0; // January
...
time_t t = mktime(&tm);

Hope this helps


----------



## Captain Code (Jan 13, 2004)

Your program should crash and not work with the wrong pointer passed.  The reason it compiles is because they are both pointers which are just 32 bit numbers.  You get a warning(which some compilers will give as an error) because the data types the pointers are for aren't matched.

You have to pass the correct type to functions.  What you are trying to do is the same thing as passing an int to something that wants a string.


----------



## havic (Jan 16, 2004)

Oops, well I feel slightly embarrassed about that now...  That will be why there was no time_t entry in the man pages.  Thanks for pointing that out rhg.

Captain Code, why would it be that my app is still running fine?  The reason I never was concerned by it is because my apps still work fine and exactly as planned, so it must be doing *something* right.
Any ideas why this is?


----------



## rhg (Jan 17, 2004)

Without having seen your code we cannot tell.


----------



## havic (Jan 18, 2004)

```
struct timespec timeNow, timeThen;
double seconds = 0;
(void) time(&timenow);
(void) time(&timeThen);

seconds = (double) (timeNow.tv_sec-timethen.tv_sec);

printf("%0.0f\n", seconds);
```

That is the way I'm assigning the two times, although in my code it is using the creation date from a stat as one of the dates, and it doesn't print it out.
The function time() doesn't take an address of a time_t, but giving it the address is the only way to make it work.


----------



## rhg (Jan 19, 2004)

time() is a POSIX function. There is no struct timespec in POSIX. I assume this is derived from struct tm. If this is the case then I the only reason your code works is that tv_sec is the very first member in struct timespec. Since time() takes a time_t as argument (yes, it does! Definitely! See man 2 time) your code works "by accident" because a time_t is a 32bit integer and timespec.tv_sec is also a 32bit integer and the first member in the struct. Any other members of timespec are however uninitialized.

I told you how to correctly deal with time_t and struct tm in my post above. Believe me, this is the only way it works, taken from real-life source code which works for years. Also, plese refer to the man pages for time(2), gettimeofday(2) and localtime(2).


----------

