2009-11-08 8 views

Antwort

36

Um die Zeit als UTC ausgedrückt zu bekommen, verwenden Sie GetSystemTime in der Win32-API.

SYSTEMTIME st; 
GetSystemTime(&st); 

SYSTEMTIME wird als mit diesen entsprechenden Mitgliedern dokumentiert:

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

Wie shf301 helfend unten weist darauf hin, GetLocalTime (mit dem gleichen Prototyp) eine Zeit, um den aktuellen Zeitzone des Benutzers korrigiert ergibt.

Sie haben hier ein paar gute Antworten, je nachdem, was Sie suchen. Wenn Sie nach nur Tageszeit suchen, ist meine Antwort der beste Ansatz - wenn Sie solide Daten für die Arithmetik benötigen, betrachten Sie Alex. Es gibt a lot of ways to skin the time cat unter Windows, und einige von ihnen sind genauer als andere (und niemand hat QueryPerformanceCounter noch erwähnt).

+5

Verwenden GetLocalTime die Zeit zu bekommen und Datum, wie der Benutzer sehen würde. http://msdn.microsoft.com/en-us/library/ms724338%28VS.85%29.aspx – shf301

+2

QueryPerformanceCounter ... Ich denke, Sie könnten Witze machen, da es viele Nachteile hat, die es zu einem schlechten machen würde Auswahl hier. –

+1

@Heath: Ja, tut mir leid, es war nicht klar. :) –

2

Je nach den Anforderungen Ihrer Anwendung gibt es sechs allgemeine Optionen. Diese Dr Dobbs Journal article gibt Ihnen alle Informationen (und mehr), die Sie brauchen, um das beste zu wählen.

In Ihrem speziellen Fall aus diesem Artikel:

GetSystemTime() die aktuelle Systemzeit abruft und instanziiert eine SYSTEMTIME-Struktur, die eine Reihe von separaten Feldern einschließlich Jahr zusammengesetzt ist, Monat , Tag, Stunden, Minuten, Sekunden und Millisekunden.

+1

Korrigieren Sie mich, wenn ich falsch liege, aber gibt GetTickCount nicht die Anzahl der Millisekunden, die seit dem Start der Anwendung vergangen sind? – Mark

+1

Ja das ist richtig, ich habe das falsche Zitat hinzugefügt. Es tut uns leid. Ich habe es jetzt behoben. – Ash

+1

@Mark: Da das System gestartet wurde. 'GetTickCount64', seit Windows Vista, erweitert das auf 64-Bit; der ehemalige ist auf 32 begrenzt. –

2

Verwendung GetSystemTime, zuerst; dann, wenn Sie das brauchen, können Sie SystemTimeToFileTime auf der SYSTEMTIME Struktur anrufen, die das ehemalige für Sie füllt. A FILETIME ist eine 64-Bit-Zählung von 100-Nanosekunden-Intervallen seit einer Epoche und daher besser für die Arithmetik geeignet; a SYSTEMTIME ist eine Struktur mit allen erwarteten Feldern (Jahr, Monat, Tag, Stunde usw. bis auf Millisekunden). Wenn Sie wissen möchten, "wie viele Millisekunden seit Mitternacht verstrichen sind", zum Beispiel Subtrahieren zwei FILETIME Strukturen (eine für die aktuelle Zeit, eine durch die Umwandlung derselben SYSTEMTIME nach dem Nullstellen der entsprechenden Felder erhalten) und Division durch die entsprechende Macht von zehn ist wahrscheinlich der einfachste verfügbare Ansatz.

+0

Jed, richtig, aus dem Speicher schreibend, dachte ich, dass es einen Unterstrich gab - Bearbeiten jetzt, um zu reparieren, tx. –

+0

Das habe ich mir gedacht. :) –

41

Die einfachste (und direkteste) Art und Weise ist GetSystemTimeAsFileTime() zu nennen, die ein FILETIME zurückgibt, eine Struktur, die die 64-Bit-Zahl von 100-Nanosekunden-Abständen speichert seit Mitternacht 1. Jan 1601

zumindest auf In der Zeit von Windows NT 3.1, 3.51 und 4.01 war die API GetSystemTimeAsFileTime() die schnellste Benutzermodus-API, die die aktuelle Uhrzeit abrufen konnte. Es bietet auch den Vorteil (verglichen mit GetSystemTime() -> SystemTimeToFileTime()), dass es sich um einen einzelnen API-Aufruf handelt, der unter normalen Umständen nicht fehlschlagen kann.

Um ein FILETIME ft_now; auf eine 64-Bit-Integer zu konvertieren ll_now genannt, die Verwendung folgende:
ll_now = (LONGLONG)ft_now.dwLowDateTime + ((LONGLONG)(ft_now.dwHighDateTime) << 32LL);

Sie können dann durch die Anzahl der 100-Nanosekunden-Abständen in einer Millisekunde (10.000 derer) unterteilen und Sie haben Millisekunden seit der Win32-Epoche.

die Unix-Epoche zu konvertieren, 116444736000000000LL subtrahiert 1. Jan erwähnt 1970.

Sie einen Wunsch zu erreichen, die Anzahl der Millisekunden in den aktuellen Tag zu finden. Da die Win32-Epoche um Mitternacht beginnt, kann die Anzahl der bisher verstrichenen Millisekunden aus der Dateizeit mit einer Modulusoperation berechnet werden. Insbesondere, weil es 24 hours/day * 60 minutes/hour * 60 seconds/minute * 1000 milliseconds/second = 86,400,000 milliseconds/day gibt, könnten Sie den Modul der Systemzeit in Millisekunden Modul 86400000LL verwenden.

Für eine andere Anwendung möchte man vielleicht nicht den Modulus verwenden. Vor allem, wenn man die verstrichenen Zeiten berechnet, könnte man Schwierigkeiten haben, um Mitternacht herumzulaufen. Diese Schwierigkeiten sind lösbar, das beste Beispiel, das mir bekannt ist, ist Linus Torvalds Linie im Linux-Kernel, die Counter-Wrap-Around-Funktionen erledigt.

Beachten Sie, dass die Systemzeit als UTC-Zeit zurückgegeben wird (sowohl bei GetSystemTimeAsFileTime() als auch einfach bei GetSystemTime()). Wenn Sie die vom Administrator konfigurierte lokale Zeit benötigen, können Sie GetLocalTime() verwenden.

+2

+1 für einen ausführlichen Zusammenbruch. Achten Sie darauf, das Bit für NT5.1 + in Bezug auf "mindestens zu der Zeit von Windows NT 3.1, 3.51 und 4.01 .. schnellste Benutzer-API" hinzuzufügen. Bedeutet es, dass es nicht länger der Fall ist? –

+1

Es bedeutet nur, dass ich nicht auf die Situation nach 4.01 schwören kann, aber tatsächlich glaube ich, dass diese API immer noch die schnellste ist. In den alten Tagen wurde es als ein paar MOV-Operationen implementiert - die SystemTimeAsFileTime wird in einer gemeinsamen Speicherseite gespeichert, die alle Prozesse lesen können. –

+1

Sehr schöne, eingehende Antwort. Um Ihre letzte Frage zu beantworten, simuliere ich ein Umgebungsszenario, in dem die Umwelt im Laufe des Tages dunkler wird (wie es im Freien der Fall wäre).Es ist nur eine Frage der Uhrzeit (in Millisekunden seit Mitternacht ist das Format, das meine Engine derzeit liest) zum Synchronisieren :) – Mark

1

Hier ist ein Code, der in Windows funktioniert, den ich in einem Open Watcom C-Projekt verwendet habe. Es sollte in C++ arbeiten Es gibt Sekunden (nicht Millisekunden) mit _dos_gettime oder 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 
} 
3

A cut-to-the-Chase Beispiel für Jed Antwort oben:

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); } 
+0

'sprintf (aktuelleZeit,"% .4d% .2d% .2d% .2d% .2d% .2d% .4d ", st.wYear, st.wMonth, st.wDay, st.wHour, stw.wMinute, st.wSecond, st.wMilliseconds); 'für eine Zeichenfolge fester Länge – Antonio

+0

Dies erhält die UTC-Zeit; 'GetLocalTime()' funktioniert ähnlich, gibt aber die lokale Zeitzone an –

Verwandte Themen