12

I want to convert a given time into epoch(time_t) and vice versa. can anyone tell what is the routine or algorithm for this?

Thanks

Update

 epoch_strt.tm_sec = 0;
 epoch_strt.tm_min = 0;
 epoch_strt.tm_hour = 0;
epoch_strt.tm_mday = 1;
epoch_strt.tm_mon = 1;
epoch_strt.tm_year = 70;
 epoch_strt.tm_isdst = -1;

double nsecs = difftime(curtime, basetime);//current time from system, I converrting it to struct tm

but this always return 32399 for some reason.

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
Yogi
  • 1,035
  • 2
  • 13
  • 39

3 Answers3

18

You should cast it to a long int instead of int.

long int t = static_cast<long int> (time(NULL));

An int might not be enough to hold the time, for example, on my platform, time_t is a typedef of __int64.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • 1
    Why not `intmax_t`? Worth nothing: `time_t` is not guaranteed to be an integer type: it is an arithmetic type, thus possibly floating point. And if the float is too large to fit in `intmax_t`, undefined behavior. POSIX guarantees this won't happen as it says time t returns seconds since EPOCH, so it cannot be that big, but ANSI C leaves it unspecified. – Ciro Santilli OurBigBook.com Jun 29 '15 at 15:09
  • 2
    This is not valid syntax. `static_cast` requires parenthesis around the source value. – em3 Sep 24 '20 at 10:15
  • Note that on some (many) platforms, `long int` is exactly the same as `int` (MSVC/Windows, for example). Maybe you were thinking of `long long int`? – Adrian Mole Dec 31 '20 at 19:31
3

Whatever you're doing with time_t, you'll probably be best off using the <chrono> library. Then you can convert to and from time_t, if necessary. Hopefully you can just do what you need in <chrono>

#include <chrono>

int main() {
    auto a = std::chrono::system_clock::now()
    time_t b = std::chrono::system_clock::to_time_t(a);
    auto c = std::chrono::system_clock::from_time_t(b);
}

Update:

The C++ standard library doesn't yet have an API for dates as good as <chrono> is for time. You can use the Boost date library or you can fall back on the C date library:

#include <ctime>
#include <chrono>
#include <iostream>

int main() {
    std::tm epoch_start = {};
    epoch_start.tm_sec = 0;
    epoch_start.tm_min = 0;
    epoch_start.tm_hour = 0;
    epoch_start.tm_mday = 1;
    epoch_start.tm_mon = 0;
    epoch_start.tm_year = 70;
    epoch_start.tm_wday = 4;
    epoch_start.tm_yday = 0;
    epoch_start.tm_isdst = -1;

    std::time_t base = std::mktime(&epoch_start);

    auto diff = std::chrono::system_clock::now() - std::chrono::system_clock::from_time_t(base);
    std::chrono::seconds s = std::chrono::duration_cast<std::chrono::seconds>(diff);

    std::cout << s.count() << '\n';
}
bames53
  • 86,085
  • 15
  • 179
  • 244
  • the year should b3 70 or 1970? – Yogi Feb 28 '12 at 15:27
  • http://en.cppreference.com/w/cpp/chrono/c/tm tm_year is years since 1970, so to represent 1970 set tm_year to 1970-1900 = 70 – bames53 Feb 28 '12 at 15:29
  • but i am using standary library. include and not chrono. – Yogi Feb 28 '12 at 15:32
  • @Yogi chrono is part of the standard library, but your implementation might not have it yet since it was just added last year. There's also an implementation in boost. If your standard library doesn't have it and you can't use boost then you can use Rob's solution with `difftime` – bames53 Feb 28 '12 at 15:37
0

To convert a struct tm to a time_t, use mktime. To convert a time_t to a struct tm, use either gmtime or localtime.

Sample:

#include <iostream>
#include <ctime>

int main () {
    std::time_t now = std::time(0);

    std::tm *now_tm = gmtime(&now);

    std::tm tomorrow_tm(*now_tm);

    tomorrow_tm.tm_mday += 1;
    tomorrow_tm.tm_hour = 0;
    tomorrow_tm.tm_min = 0;
    tomorrow_tm.tm_sec = 0;

    std::time_t tomorrow = std::mktime(&tomorrow_tm);

    double delta = std::difftime(tomorrow, now);

    std::cout << "Tomorrow is " << delta << " seconds from now.\n";
}


UPDATE 2
#include <iostream>
#include <ctime>
#include <cassert>

// Display the difference between now and 1970-01-01 00:00:00
// On my computer, this printed the value 1330421747
int main () {

    std::tm epoch_strt;
    epoch_strt.tm_sec = 0;
    epoch_strt.tm_min = 0;
    epoch_strt.tm_hour = 0;
    epoch_strt.tm_mday = 1;
    epoch_strt.tm_mon = 0;
    epoch_strt.tm_year = 70;
    epoch_strt.tm_isdst = -1;

    std::time_t basetime = std::mktime(&epoch_strt);

    std::time_t curtime = std::time(0);

    long long nsecs = std::difftime(curtime, basetime);

    std::cout << "Seconds since epoch: " << nsecs << "\n";
    assert(nsecs > 42ll * 365 * 24 * 60 * 60);
}
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • Can you please tell me for epoch date i.e 1st Jan 1970?. – Yogi Feb 28 '12 at 15:10
  • Download my 2nd sample program above, and replace the `epoch_strt … = 0` lines with what you need. – Robᵩ Feb 28 '12 at 15:12
  • I did that but I dont know why its returning zero. I am using long long for nsec, but when I print nothing appears – Yogi Feb 28 '12 at 15:24