Как мне преобразовать строку, содержащую 64-битное время эпохи, в читаемый человеком формат?

0

Поэтому я понял, что строка, которую я получаю с сервера, который представляет дату, представляет собой 64-битное представление времени с эпохи. Например, одно из значений, которое я получаю, это: 1380994682285. Я пробовал делать atoi в строке, но, очевидно, это не работает, поскольку я теряю точность и получающееся значение, которое я передаю в localtime(), приводит к неправильная дата. Это на iOS, поэтому некоторые телефоны 32 бит, а некоторые из них 64 бит, и в настоящее время я вижу, что он имеет time_t, определенный как длинный. Как я могу преобразовать это большое значение эпохи в то, что я могу, в конечном счете, получить от человека с удобочитаемой даты?

  • 1
    Попробуй std::stoull .
  • 0
    Что я передам это потом? localtime занимает time_t, которое на моей платформе определяется как long.
Показать ещё 1 комментарий
Теги:
epoch

3 ответа

1
Лучший ответ

Поскольку кажется, что вы просите 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".

  • 1
    Я люблю вас! Это сработало отлично, спасибо. И да, C ++ был тем, чем я занимался, поскольку я пишу в нем свой переносимый код, а не цель-c. Благодаря тонну!
  • 0
    Остерегайтесь того факта, что последние три символа должны быть частью числа: если у вас есть завершающие пробелы, символ новой строки или другой мусор, strlen(d)-3 не будет правильно «усекать» входную строку.
0

Строка - это эпоха эпохи UNIX в миллисекундах, поэтому существует простое исправление: отбросьте последние три символа, и результатом будет период времени в UNIX в секундах (который будет вписываться в 32-битное целое число до 2038).

0

Как замечает Kerrek SB, посмотрите на набор функций std::sto*. std::stol преобразует строку в long, а std::stoull будет преобразовывать строку в unsigned long long. Если вы храните это в time_t, вы можете передать его в localtime без каких-либо проблем.

  • 0
    Я не могу этого сделать, потому что time_t определен как long, поэтому я теряю точность при выполнении std :: stoull, и поэтому мои даты оказываются неверными.
  • 0
    @Architekt вы потеряли бы точность только с std :: stoull, если бы ваша строка времени эпохи не могла вписаться в time_t. Который все равно потерял бы точность с std :: stol. Использование std :: stoull означает, что даже на других платформах, где time_t может быть больше, вы все равно получите точный ответ (с точностью до time_t)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню