web-dev-qa-db-fra.com

Conversion de l'heure de l'époque en date / heure "réelle"

Ce que je veux faire, c'est convertir un temps Epoch (secondes depuis minuit 1/1/1970) en temps "réel" (m/d/y h: m: s)

Jusqu'à présent, j'ai l'algorithme suivant, qui me semble un peu moche:

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

vous pouvez supposer que les membres seconds, minutes, hours, month, day et year existent tous .

L'utilisation des boucles for pour modifier l'heure d'origine semble un peu décalée, et je me demandais s'il y avait une "meilleure" solution à cela.

23
Austin Hyde

Faites attention aux années bissextiles dans votre fonction daysInMonth.

Si vous voulez des performances très élevées, vous pouvez précalculer la paire pour obtenir le mois + l'année en une seule étape, puis calculer le jour/heure/min/sec.

Une bonne solution est celle du code source 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;
}
18
rxin

La bibliothèque standard fournit des fonctions pour ce faire. gmtime() ou localtime() convertira un time_t (secondes depuis l'époque, c'est-à-dire 1er janvier 1970 00:00:00) en un struct tm. strftime() peut ensuite être utilisé pour convertir un struct tm en une chaîne (char*) selon le format que vous spécifiez.

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

Les calculs de date/heure peuvent devenir délicats. Il vaut mieux utiliser une solution existante plutôt que d'essayer de lancer la vôtre, sauf si vous avez une très bonne raison.

14
sdtom

Un moyen simple (bien que différent du format que vous vouliez):

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

Sortie: mer 21 sept 10:27:52 2011

Notez que le résultat retourné sera automatiquement concaténé avec "\ n" .. vous pouvez le supprimer en utilisant:

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

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

3
brkeyal
time_t t = unixTime;
cout << ctime(&t) << endl;
1
user4513421

Si votre type d'heure d'origine est time_t, vous devez utiliser les fonctions de time.h c'est-à-dire gmtime etc. pour obtenir le code portable. Les normes C/C++ ne spécifient pas de format interne (ni même de type exact) pour time_t, vous ne pouvez donc pas convertir ni manipuler directement les valeurs de time_t.

Tout ce que l'on sait, c'est que time_t est de "type arithmétique", mais les résultats des opérations arithmétiques ne sont pas spécifiés - vous ne pouvez même pas ajouter/soustraire de manière fiable. En pratique, de nombreux systèmes utilisent un type entier pour time_t avec un format interne de secondes depuis Epoch, mais cela n'est pas imposé par les normes.

En bref, utilisez gmtime (et la fonctionnalité time.h en général).

0
eidolon