web-dev-qa-db-fra.com

Obtenir l'heure actuelle (en millisecondes) de l'horloge système sous Windows?

Comment obtenir l'heure actuelle de l'horloge système (en millisecondes) en C++? Ceci est une application spécifique à Windows.

34
Mark

Pour obtenir l'heure exprimée en UTC, utilisez GetSystemTime dans l'API Win32.

SYSTEMTIME st;
GetSystemTime(&st);

SYSTEMTIME est documenté comme ayant ces membres pertinents:

Word wYear;
Word wMonth;
Word wDayOfWeek;
Word wDay;
Word wHour;
Word wMinute;
Word wSecond;
Word wMilliseconds;

Comme shf301 le souligne utilement ci-dessous, GetLocalTime (avec le même prototype) donnera une heure corrigée au fuseau horaire actuel de l'utilisateur.

Vous avez ici quelques bonnes réponses, selon ce que vous recherchez. Si vous recherchez juste l'heure de la journée, ma réponse est la meilleure approche - si vous avez besoin de dates solides pour l'arithmétique, pensez à Alex. Il y a beaucoup de façons d'habiller le chat temporel sur Windows, et certains d'entre eux sont plus précis que d'autres (et personne n'a mentionné QueryPerformanceCounter pour l'instant).

40
Jed Smith

Le moyen le plus simple (et le plus direct) consiste à appeler GetSystemTimeAsFileTime(), qui renvoie un FILETIME, une structure qui stocke le nombre 64 bits d'intervalles de 100 nanosecondes depuis le 1er janvier 1601 à minuit.

Au moins au moment de Windows NT 3.1, 3.51 et 4.01, l'API GetSystemTimeAsFileTime() était l'API en mode utilisateur la plus rapide capable de récupérer l'heure actuelle. Il offre également l'avantage (par rapport à GetSystemTime () -> SystemTimeToFileTime ()) d'être un seul appel d'API, qui dans des circonstances normales ne peut pas échouer.

Pour convertir un FILETIME ft_now; En un entier 64 bits nommé ll_now, Utilisez ce qui suit:
ll_now = (LONGLONG)ft_now.dwLowDateTime + ((LONGLONG)(ft_now.dwHighDateTime) << 32LL);

Vous pouvez ensuite diviser par le nombre d'intervalles de 100 nanosecondes dans une milliseconde (10 000 d'entre eux) et vous avez des millisecondes depuis l'époque Win32.

Pour convertir à l'époque Unix, soustrayez 116444736000000000LL Pour atteindre le 1er janvier 1970.

Vous avez mentionné le désir de trouver le nombre de millisecondes dans la journée en cours. Étant donné que l'époque Win32 commence à minuit, le nombre de millisecondes écoulées jusqu'à présent aujourd'hui peut être calculé à partir de la durée de fichier avec une opération de module. Plus précisément, comme il y a 24 hours/day * 60 minutes/hour * 60 seconds/minute * 1000 milliseconds/second = 86,400,000 milliseconds/day, Vous pouvez utiliser le module de l'heure système en module de millisecondes 86400000LL.

Pour une application différente, on peut ne pas vouloir utiliser le module. Surtout si l'on calcule les temps écoulés, on peut avoir des difficultés à boucler à minuit. Ces difficultés sont résolubles, le meilleur exemple que je connaisse est la ligne de Linus Torvald dans le noyau Linux qui gère le retour à la ligne.

Gardez à l'esprit que l'heure système est renvoyée sous la forme d'une heure UTC (à la fois dans le cas de GetSystemTimeAsFileTime() et simplement GetSystemTime()). Si vous avez besoin de l'heure locale telle que configurée par l'administrateur, vous pouvez alors utiliser GetLocalTime().

49
Heath Hunnicutt

Un exemple précis de la réponse de Jed ci-dessus:

const std::string currentDateTime() {

SYSTEMTIME st, lt;

GetSystemTime(&st);

char currentTime[84] = "";

sprintf(currentTime,"%d/%d/%d  %d:%d:%d %d",st.wDay,st.wMonth,st.wYear, st.wHour, st.wMinute, st.wSecond , st.wMilliseconds);

return string(currentTime); }
7
SteveCav

Utilisez GetSystemTime , d'abord; ensuite, si vous en avez besoin, vous pouvez appeler SystemTimeToFileTime sur la structure SYSTEMTIME que la première remplit pour vous. Un FILETIME est un décompte de 64 bits d'intervalles de 100 nanosecs depuis une époque, et donc plus adapté à l'arithmétique; a SYSTEMTIME est une structure avec tous les champs attendus (année, mois, jour, heure, etc., en millisecondes). Si vous voulez savoir "combien de millisecondes se sont écoulées depuis minuit", par exemple, en soustrayant deux structures FILETIME (une pour l'heure actuelle, une obtenue en convertissant la même SYSTEMTIME après avoir mis à zéro le domaines appropriés) et la division par la puissance appropriée de dix est probablement l'approche la plus simple disponible.

3
Alex Martelli

Selon les besoins de votre application, il existe six options communes. Cette article du Dr Dobbs Journal vous donnera toutes les informations (et plus) dont vous avez besoin pour choisir la meilleure.

Dans votre cas spécifique, à partir de cet article:

GetSystemTime () récupère l'heure système actuelle et instancie une structure SYSTEMTIME, qui est composée d'un certain nombre de champs distincts, y compris l'année, le mois, le jour, les heures, les minutes, les secondes et les millisecondes.

2
Ash

Voici du code qui fonctionne sous Windows que j'ai utilisé dans un projet Open Watcom C. Cela devrait fonctionner en C++ Il retourne des secondes (pas des millisecondes) en utilisant _dos_gettime ou gettime

  double seconds(void)
  {
  #ifdef __WATCOMC__
  struct dostime_t t;
  _dos_gettime(&t);
  return ((double)t.hour * 3600 + (double)t.minute * 60 + (double)t.second + (double)t.hsecond * 0.01);
  #else
  struct time t;
  gettime(&t);
  return ((double)t.ti_hour * 3600 + (double)t.ti_min * 60 + (double)t.ti_sec + (double)t.ti_hund * 0.01);
  #endif
}
1
user1231247