8

I want to extract hours, minutes and seconds as integer values from a time_t value representing seconds since epoch.

The value for hours is not correct. Why?

#include <stdio.h>
#include <time.h>

#include <unistd.h>

int main()
{
    char buf[64];

    while (1) {
        time_t t = time(NULL);
        struct tm *tmp = gmtime(&t);

        int h = (t / 360) % 24;  /* ### My problem. */
        int m = (t / 60) % 60;
        int s = t % 60;

        printf("%02d:%02d:%02d\n", h, m, s);

        /* For reference, extracts the correct values. */
        strftime(buf, sizeof(buf), "%H:%M:%S\n", tmp);
        puts(buf);
        sleep(1);
    }
}

Output (the hour should be 10)

06:15:35
10:15:35

06:15:36
10:15:36

06:15:37
10:15:37
Abhineet
  • 5,320
  • 1
  • 25
  • 43
Daniel Näslund
  • 2,300
  • 3
  • 22
  • 27
  • "int h = (t / 3600) % 24; ..." makes the _assumption_ the `time_t` is in integer seconds. Although that is common, it is not defined to be so by C. Use `gmtime()/localtime()` or `difftime()` for portable code. – chux - Reinstate Monica Mar 03 '17 at 18:36

2 Answers2

15
int h = (t / 3600) % 24;  /* ### Your problem. */
Adam Sznajder
  • 9,108
  • 4
  • 39
  • 60
8

Your call to gmtime() already does it, the resulting struct tm has all the fields. See the documentation.

In other words, just

printf("hours is %d\n", tmp->tm_hour);

I would argue that this is the proper way, since it avoids involving scarily large numbers to do the conversion manually in your code. It does so in the best of ways, by making it Someone Else's Problem (i.e., abstracting it away). So fix your code not by adding the missing 0, but by using gmtime().

Also think about timezones.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 1
    Thanks, but the question was: Why is the calculation not correct. (I agree that using struct tm is a better approach though). – Daniel Näslund Jun 28 '12 at 10:33
  • 2
    @dannas: Cuz you are dividing as: t/360 where it should be t/3600 (remember 60 * 60) – Abhineet Jun 28 '12 at 10:37
  • Hm, the question actually was: "how extract hours from time_t" (in the problem spec I added the other question). Accepting the answer since it gives a good reason as to why I should avoid doing the conversion myself. – Daniel Näslund Jun 28 '12 at 10:44