Convertir la date / heure en horodatage et vice versa

J’essaie d’implémenter en C deux convertisseurs simples, date / heure et horodatage et vice-versa, sans aucune dépendance des routines de bibliothèque de temps, telles que mktime, etc.

L’horodatage est en secondes et la structure de date / heure est au format suivant:

  • Année de caractère non signée: 0 à 99 (représentant la plage de 2000 à 2099)

  • mois non signé: 1 à 12

  • Jour de char non signé: 1 à 31

  • heure du personnage non signé: 0 à 23

  • minute signée: 0 à 59

  • Caractère non signé en seconde: 0 à 59

Je voudrais avoir un deuxième avis sur le convertisseur dt2ts (en supposant que l’entrée est légale):

unsigned int dt2ts(const dt_t* dt) { static unsigned short days[] = {0,31,59,90,120,151,181,212,243,273,304,334}; return ((((dt->year*365+dt->year/4)+days[dt->month-1]+dt->day)*24+dt->hour)*60+dt->minute)*60+dt->second; } 

En plus de cela, j’apprécierais de l’aide pour compléter le convertisseur ts2dt:

 void ts2dt(unsigned int ts,dt_t* dt) { dt->second = ts%60; ts /= 60; dt->minute = ts%60; ts /= 60; dt->hour = ts%24; ts /= 24; dt->day = ?????; dt->month = ?????; dt->year = ?????; } 

Merci

    OP est tout prêt à gérer les heures, les minutes et les secondes. Juste un peu d’aide sur Y, M, D.

    Remarque: le nombre de jours compris entre le 1er janvier 2000 et le 31 décembre 2099 nécessite au moins un entier de 16 bits. Ce qui suit devrait fonctionner même si unsigned est 2 octets.

     unsigned DivRem(unsigned Dividend, unsigned Divisor, unsigned *Remainder) { unsigned Quotient = Dividend/Divisor; *Remainder = Dividend - Quotient*Divisor; return Quotient; } void Day2000ToYMD(unsigned DaySince2000Jan1, unsigned *Y, unsigned *M, unsigned *D) { unsigned OlympiadDay; // Every 4 years is an Olympiad *Y = 4*DivRem(DaySince2000Jan1, 365*4+1, &OlympiadDay); *D = 1; if (OlympiadDay >= (31+29-1)) { // deal with Feb 29th and after OlympiadDay--; if (OlympiadDay == (31+29-1)) { (*D)++; } } unsigned YearDay; // Day of the year 0 to 364 *Y += DivRem(OlympiadDay, 365, &YearDay); static const unsigned short days[] = {0,31,59,90,120,151,181,212,243,273,304,334,365}; *M = 1; while (days[*M] <= YearDay) (*M)++; *D += YearDay - days[*M - 1]; } 

    [Edit] La réponse fournie essaye de garder le concept de l'année du 1er janvier au 31 décembre. Comme cette réponse n'a pas besoin de gérer les années bissextiles environ 100 et 400 ans, j'ai conservé ce style.

    En général, une fois que ces 2 règles sont ajoutées, le calcul devient plus facile si on reporte le début de l'année au 1er mars et se termine le 28/29 février. FWIW, il s’agit d’ une vision plus cohérente de l’ancien développement du calendrier julien / grégorien. Ainsi, * octobre * octobre est alors le 8ème mois et * décembre * est le 10ème mois.