2 votes

Convertir un horodatage Unix en une date lisible par l'homme

Y a-t-il un moyen contemporain de convertir des horodatages Unix en une date lisible par l'homme? Puisque je veux contourner le problème de l'an 2038, je veux utiliser des int64s. Je vise à convertir par exemple 1205812558 en

année = 2008, mois = 3, jour = 18, heure = 17, minute = 18, seconde = 36

Tout ce que j'ai c'est maintenant

auto année = totalSeconds / secondsPerYear + 1970;
// mois et jour manquants
auto heures = totalSeconds / 3600 % 24;
auto minutes = totalSeconds / 60 % 60;
auto secondes = totalSeconds % 60;

2voto

Howard Hinnant Points 59526

En C++20 (selon le spécification provisoire pour C++20 telle qu'elle se présente aujourd'hui), vous pourrez dire :

#include 
#include 

int
main()
{
    using namespace std;
    using namespace std::chrono;
    cout << sys_seconds{1205812558s} << '\n';
    cout << sys_seconds{32879409516s} << '\n';
}

et cela va afficher :

2008-03-18 03:55:58
3011-11-28 17:18:36

Il s'agit d'horodatages en UTC.

Vous pouvez utiliser la bibliothèque de dates de Howard Hinnant pour expérimenter avec cette fonctionnalité étendue dès aujourd'hui en ajoutant :

#include "date/date.h"

et

    using namespace date;

au programme ci-dessus. Vous pouvez expérimenter en ligne avec ce programme ici.


Un commentaire ci-dessous demande à quoi cela ressemble si la valeur est stockée dans uint64_t. La réponse est que vous devez convertir le type intégral en seconds, puis les seconds en sys_seconds :

uint64_t i = 1205812558;
cout << sys_seconds{seconds(i)} << '\n';

Il existe des limites à cette fonctionnalité contemporaine, mais elles se situent aux alentours des années +/-32K (bien au-delà des limites de l'exactitude du calendrier civil actuel).

Pour être totalement transparent, il existe des moyens de le faire en utilisant seulement C++98/11/14/17, mais ils sont plus compliqués que cela, et sont sujets à des bugs de multithreading. Cela est dû à l'utilisation d'une API C désuète qui a été conçue avant l'avènement de choses comme le multithreading et le C++, et quand l'année 2001 n'était associée qu'à la science-fiction (par exemple gmtime).

1voto

Alan Birtles Points 12524

La bibliothèque de dates de Howard Hinnant rend les choses assez faciles :

#include "date.h"

int main()
{
    using namespace date;
    time_t time = 32879409516;
    auto sysTime = std::chrono::system_clock::from_time_t(time);
    auto date = year_month_day(floor(sysTime));
    std::cout << date << "\n";
}

0voto

TKA Points 198

Une bonne solution directe mais pourrait nécessiter quelques modifications mineures :

uint32_t jours = (uint32_t)floor(subt / 86400);
uint32_t heures = (uint32_t)floor(((subt - jours * 86400) / 3600) % 24);
uint32_t minutes = (uint32_t)floor((((subt - jours * 86400) - heures * 3600) / 60) % 60);
uint32_t secondes = (uint32_t)floor(((((subt - jours * 86400) - heures * 3600) - minutes * 60)) % 60);
printf("Temps restant : %u Jours, %u Heures, %u Minutes, %u Secondes\n", jours, heures, minutes, secondes);

-1voto

Navaneeth Points 27

Pas besoin de bibliothèques externes. J'utilise :

uint32_t days =     (uint32_t)floor(subt / 86400);
uint32_t hours =    (uint32_t)floor( ( (subt - days) / 3600) % 24 );
uint32_t minutes =  (uint32_t)floor( ( ( ( subt - days) - hours) / 60) % 60 );
uint32_t seconds =  (uint32_t)floor( ( ( ( ( subt - days ) - hours ) - minutes ) ) % 60 );
printf("Temps restant : %u Jours, %u Heures, %u Minutes, %u Secondes\n", days, hours, minutes, seconds);

subt est un timestamp unix. J'espère que cela t'aidera :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X