4
votes

I'd like to get the unix timestamp of the beginning of current (or any given maybe) hour in c/c++.

I have this:


    time_t get_current_hour() {
        time_t beginning_of_hour;
        struct tm * ptm;

        time(&beginning_of_hour);

        ptm = gmtime(&beginning_of_hour);
        ptm->tm_min = 0;
        ptm->tm_sec = 0;
        ptm->tm_zone = (char*) "GMT";

        beginning_of_hour = mktime(ptm);

        return beginning_of_hour;
    }

Which works, but under high load many of the result are not the beginning of the current hour but the actual time.

Is there a better way to solve the problem? Why does the function returns the current time?

Please advise, Akos

3

3 Answers

7
votes

You can do it all with time_t, without breaking it apart and rebuilding.
Just round it down to a multiple of 3600:

time_t get_current_hour(void) {
    time_t now;
    time(&now);
    return now - (now % 3600);
}

Perhaps it isn't nice to treat time_t as an integer. But I think it is guaranteed to be seconds since the epoch, so it should be fine.

1
votes

It could be that you have a multi-threaded application, and calls to gmtime are not thread-safe (re-entrant). If this is the case, try using the re-entrant version: gmtime_r

0
votes

Is your application by any chance multi-threaded? gmtime returns a pointer to static memory, which will be overwritten the next time the function is called. Such functions are not thread-safe (and this is about the only thing I can think of which would account for your symptoms). Under Unix, there is also a gmtime_r, which allows you to declare a local buffer, and avoid the issue; Windows has a _gmtime_s which is (I think) similar.