Поэтому я понял, что строка, которую я получаю с сервера, который представляет дату, представляет собой 64-битное представление времени с эпохи. Например, одно из значений, которое я получаю, это: 1380994682285. Я пробовал делать atoi в строке, но, очевидно, это не работает, поскольку я теряю точность и получающееся значение, которое я передаю в localtime(), приводит к неправильная дата. Это на iOS, поэтому некоторые телефоны 32 бит, а некоторые из них 64 бит, и в настоящее время я вижу, что он имеет time_t, определенный как длинный. Как я могу преобразовать это большое значение эпохи в то, что я могу, в конечном счете, получить от человека с удобочитаемой даты?
Поскольку кажется, что вы просите C++, я добавляю этот ответ. Комментарии пытаются объяснить проблемы, связанные с тем, что ваше входное значение не будет вписываться в 32-битную переменную, и если вы не можете иметь 64-битную переменную, вам нужно "разделить" до этого, удалив последние три символа, как предлагает duskwuff.
#include <sstream>
#include <iostream>
#include <cstring>
#include <ctime>
// uint64_t ... gcc complains it 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;
}
Эти ответы не обрабатывают ошибки, например, случай, когда потоковая передача не может читать целое число, например, когда у вас есть "строка" вместо "1234".
strlen(d)-3
не будет правильно «усекать» входную строку.
Строка - это эпоха эпохи UNIX в миллисекундах, поэтому существует простое исправление: отбросьте последние три символа, и результатом будет период времени в UNIX в секундах (который будет вписываться в 32-битное целое число до 2038).
Как замечает Kerrek SB, посмотрите на набор функций std::sto*
. std::stol
преобразует строку в long, а std::stoull
будет преобразовывать строку в unsigned long long. Если вы храните это в time_t
, вы можете передать его в localtime
без каких-либо проблем.
std::stoull
.