How do I convert a string containing a 64 bit epoch time to human readable format?

StackOverflow https://stackoverflow.com/questions/21069389

  •  27-09-2022
  •  | 
  •  

문제

So I realized that the string I'm getting from a server that represents the date is a 64 bit representation of the time since the epoch. For example, one of the values I'm getting is: 1380994682285. I've tried doing an atoi on the string but obviously that doesn't work as I lose precision and the resultant value that I pass on to localtime() results in an incorrect date. This is on iOS so some phones are 32 bit and some are 64 bit, and presently, I see that it has time_t defined as a long. How do I convert this large epoch value to something I can ultimately get a human readable date from?

도움이 되었습니까?

해결책

Since it seems you are asking for C++, I add this answer. Comments try to explain issues about the fact that your input value won't fit into a 32bit variable, and if you can't have a 64bit variable, you need to "divide" before, by removing last three chars as duskwuff answer suggests.

#include <sstream>
#include <iostream>
#include <cstring>
#include <ctime>

// uint64_t ... gcc complains it's a C++11 stuff
//#include <cinttypes>

int main()
{
    const char *d = "1380994682285";

    std::stringstream is(d);

    // ISO C++98 does not support long long
    // ... it should be uint64_t, but supported in C++11...
    // or rather, just long but be sure you compile for 64bit
    std::cout << sizeof (long) << "\n";       // very likely 4 on 32bit
    std::cout << sizeof (long long) << "\n";  // 8
    unsigned long long epoch64;
    // if you need strict ISO C++98 conformance, you must use unsigned long,
    // see below.

    is >> epoch64;

    std::cout << epoch64 << "\n";
    epoch64 /= 1000;
    // this goes ok (if epoch64 is big enough), since /1000 makes it
    // small enough to go into time_t
    time_t t = epoch64;

    std::cout << std::ctime(&t) << "\n";

    // if you use unsigned long for epoch, and it turns out to
    // be sizeof (unsigned long) == 4, then you get the wrong output.
    // Then, you must make it shorter before to convert it:
    std::string shorter(d, strlen(d)-3); // assert(strlen(d)>3)
    std::stringstream is2(shorter);

    unsigned long epoch32; // I am on a 32bit machine
    is2 >> epoch32;
    t = epoch32;
    std::cout << epoch32 << "\n";
    std::cout << std::ctime(&t) << "\n";

    return 0;
}

This answers does not handle errors, e.g. the case when streaming is not able to read an integer, e.g. when you have "a string" instead of "1234".

다른 팁

As Kerrek SB put in a comment, have a look at the std::sto* set of functions. std::stol will convert a string to a long, and std::stoull will convert a string to an unsigned long long. If you store that in a time_t, you can pass it to localtime without any problems.

The string is a UNIX epoch time in milliseconds, so there's an easy fix: Chop off the last three characters, and the result will be a UNIX epoch time in seconds (which will fit into a 32-bit integer until 2038).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top