Подтвердить что ты не робот

Преобразование эпохи в "настоящую" дату/время

То, что я хочу сделать, - это преобразовать время эпохи (секунды с полуночи 1/1/1970) в "реальное" время (m/d/y h: m: s)

До сих пор у меня есть следующий алгоритм, который мне кажется немного уродливым:

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;
}

вы можете предположить, что существуют члены seconds, minutes, hours, month, day и year.

Использование циклов for для изменения первоначального времени немного немного, и мне было интересно, есть ли "лучшее" решение для этого.

4b9b3361

Ответ 1

Будьте осторожны с високосными годами в вашей функции daysInMonth.

Если вы хотите очень высокую производительность, вы можете предварительно скопировать пару, чтобы перейти на месяц + год за один шаг, а затем рассчитать день/час/мин/сек.

Хорошим решением является исходный код 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        <time.h>
#include        <limits.h>
#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;
}

Ответ 2

Стандартная библиотека предоставляет функции для этого. gmtime() или localtime() преобразует time_t (секунды с эпохи) в структуру tm. strftime() может затем использоваться для преобразования struct tm в строку на основе указанного вами формата.

см. http://www.cplusplus.com/reference/clibrary/ctime/

Расчеты даты/времени могут оказаться сложными. Вам гораздо лучше использовать существующее решение, вместо того чтобы пытаться катиться самостоятельно, если у вас нет действительно веской причины.

Ответ 3

Простым способом (хотя и отличается от формата, который вы хотели):

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

Вывод: Ср Сен 21 10:27:52 2011

Обратите внимание, что возвращенный результат будет автоматически связан с "\n".. вы можете удалить его, используя:

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

Взято из: http://en.cppreference.com/w/cpp/chrono/c/time

Ответ 4

Если ваш исходный тип времени - time_t, вы должны использовать функции from time.h, т.е. gmtime и т.д., чтобы получить переносимый код. Стандарты C/С++ не определяют внутренний формат (или даже точный тип) для time_t, поэтому вы не можете напрямую преобразовывать или изменять значения time_t.

Все, что известно, это то, что time_t является "арифметическим типом", но результаты арифметических операций не указаны - вы даже не можете надежно добавить/вычесть. На практике многие системы используют целочисленный тип для time_t с внутренним форматом секунд с эпохи, но это не соблюдается стандартами.

Короче говоря, используйте функции gmtime (и time.h в целом).