Convertendo tempo de época para data / hora “real”

O que eu quero fazer é converter um tempo de época (segundos desde a meia-noite de 1/1/1970) para o horário “real” (m / d / yh: m: s)

Até agora, tenho o seguinte algoritmo, que para mim parece um pouco feio:

void DateTime::splitTicks(time_t time) { seconds = time % 60; time /= 60; minutes = time % 60; time /= 60; hours = time % 24; time /= 24; year = DateTime::reduceDaysToYear(time); month = DateTime::reduceDaysToMonths(time,year); day = int(time); } int DateTime::reduceDaysToYear(time_t &days) { int year; for (year=1970;days>daysInYear(year);year++) { days -= daysInYear(year); } return year; } int DateTime::reduceDaysToMonths(time_t &days,int year) { int month; for (month=0;days>daysInMonth(month,year);month++) days -= daysInMonth(month,year); return month; } 

Você pode assumir que os membros seconds , minutes , hours , month , day e year existem.

Usar os loops for para modificar o tempo original parece um pouco fora, e eu queria saber se existe uma solução “melhor” para isso.

Tenha cuidado com anos bissextos em sua function daysInMonth.

Se você quiser um desempenho muito alto, você pode pré-calcular o par para chegar ao mês + ano em uma etapa e, em seguida, calcular o dia / hora / min / seg.

Uma boa solução é a do código fonte do gmtime :

 /* * gmtime - convert the calendar time into broken down time */ /* $Header: gmtime.c,v 1.4 91/04/22 13:20:27 ceriel Exp $ */ #include  #include  #include "loc_time.h" struct tm * gmtime(register const time_t *timer) { static struct tm br_time; register struct tm *timep = &br_time; time_t time = *timer; register unsigned long dayclock, dayno; int year = EPOCH_YR; dayclock = (unsigned long)time % SECS_DAY; dayno = (unsigned long)time / SECS_DAY; timep->tm_sec = dayclock % 60; timep->tm_min = (dayclock % 3600) / 60; timep->tm_hour = dayclock / 3600; timep->tm_wday = (dayno + 4) % 7; /* day 0 was a thursday */ while (dayno >= YEARSIZE(year)) { dayno -= YEARSIZE(year); year++; } timep->tm_year = year - YEAR0; timep->tm_yday = dayno; timep->tm_mon = 0; while (dayno >= _ytab[LEAPYEAR(year)][timep->tm_mon]) { dayno -= _ytab[LEAPYEAR(year)][timep->tm_mon]; timep->tm_mon++; } timep->tm_mday = dayno + 1; timep->tm_isdst = 0; return timep; } 

A biblioteca padrão fornece funções para isso. gmtime() ou localtime() irá converter um time_t (segundos desde a época, ie – 1 de janeiro de 1970 00:00:00) em um struct tm . strftime() pode então ser usado para converter uma struct tm em uma string ( char* ) baseada no formato que você especificar.

veja: http://www.cplusplus.com/reference/clibrary/ctime/

Cálculos de data / hora podem ser complicados. Você está muito melhor em usar uma solução existente do que tentar rolar a sua própria, a menos que tenha uma boa razão.

Uma maneira fácil (embora diferente do formato que você queria):

 std::time_t result = std::time(nullptr); std::cout << std::asctime(std::localtime(&result)); 

Resultado: quarta-feira, 21 de setembro, 10:27:52 2011

Observe que o resultado retornado será automaticamente concatenado com "\ n" .. você pode removê-lo usando:

 std::string::size_type i = res.find("\n"); if (i != std::string::npos) res.erase(i, res.length()); 

Retirado de: http://en.cppreference.com/w/cpp/chrono/c/time

Se o seu tipo de hora original for time_t, você terá que usar as funções time.h, gmtime etc., para obter o código portátil. Os padrões C / C ++ não especificam o formato interno (ou mesmo o tipo exato) para o time_t, portanto você não pode converter ou manipular diretamente os valores time_t.

Tudo o que se sabe é que time_t é “tipo aritmético”, mas os resultados das operações aritméticas não são especificados – você não pode nem mesmo adicionar / subtrair de forma confiável. Na prática, muitos sistemas usam o tipo inteiro para time_t com o formato interno de segundos desde a época, mas isso não é imposto pelos padrões.

Em suma, use o gmtime (e a funcionalidade time.h em geral).

 time_t t = unixTime; cout << ctime(&t) << endl;