C++ 从 Windows 的系统时钟获取当前时间(以毫秒为单位)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1695288/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting the current time (in milliseconds) from the system clock in Windows?
提问by Mark
How can you obtain the system clock's current time of day (in milliseconds) in C++? This is a windows specific app.
如何在 C++ 中获取系统时钟的当前时间(以毫秒为单位)?这是一个 Windows 特定的应用程序。
回答by Heath Hunnicutt
The easiest (and most direct) way is to call GetSystemTimeAsFileTime()
, which returns a FILETIME
, a struct which stores the 64-bit number of 100-nanosecond intervals since midnight Jan 1, 1601.
最简单(也是最直接)的方法是调用GetSystemTimeAsFileTime()
,它返回一个FILETIME
结构,它存储自 1601 年 1 月 1 日午夜以来 100 纳秒间隔的 64 位数字。
At least at the time of Windows NT 3.1, 3.51, and 4.01, the GetSystemTimeAsFileTime()
API was the fastest user-mode API able to retrieve the current time. It also offers the advantage (compared with GetSystemTime() -> SystemTimeToFileTime()) of being a single API call, that under normal circumstances cannot fail.
至少在 Windows NT 3.1、3.51 和 4.01 的时候,GetSystemTimeAsFileTime()
API 是能够检索当前时间的最快的用户模式 API。它还提供了作为单个 API 调用的优势(与 GetSystemTime() -> SystemTimeToFileTime() 相比),在正常情况下不会失败。
To convert a FILETIME ft_now;
to a 64-bit integer named ll_now
, use the following:ll_now = (LONGLONG)ft_now.dwLowDateTime + ((LONGLONG)(ft_now.dwHighDateTime) << 32LL);
要将 a 转换为FILETIME ft_now;
名为 的 64 位整数ll_now
,请使用以下命令:ll_now = (LONGLONG)ft_now.dwLowDateTime + ((LONGLONG)(ft_now.dwHighDateTime) << 32LL);
You can then divide by the number of 100-nanosecond intervals in a millisecond (10,000 of those) and you have milliseconds since the Win32 epoch.
然后,您可以除以一毫秒内 100 纳秒间隔的数量(其中 10,000 个),并且您有自 Win32 时代以来的毫秒数。
To convert to the Unix epoch, subtract 116444736000000000LL
to reach Jan 1, 1970.
要转换到 Unix 纪元,减去116444736000000000LL
到 1970 年 1 月 1 日。
You mentioned a desire to find the number of milliseconds into the current day. Because the Win32 epoch begins at a midnight, the number of milliseconds passed so far today can be calculated from the filetime with a modulus operation. Specifically, because there are 24 hours/day * 60 minutes/hour * 60 seconds/minute * 1000 milliseconds/second = 86,400,000 milliseconds/day
, you could user the modulus of the system time in milliseconds modulus 86400000LL
.
您提到希望找到当天的毫秒数。因为 Win32 纪元从午夜开始,所以可以通过模数运算从文件时间计算到目前为止经过的毫秒数。具体来说,因为有24 hours/day * 60 minutes/hour * 60 seconds/minute * 1000 milliseconds/second = 86,400,000 milliseconds/day
,您可以使用系统时间的模数(以毫秒为单位)86400000LL
。
For a different application, one might not want to use the modulus. Especially if one is calculating elapsed times, one might have difficulties due to wrap-around at midnight. These difficulties are solvable, the best example I am aware is Linus Torvald's line in the Linux kernel which handles counter wrap around.
对于不同的应用程序,人们可能不想使用模数。尤其是在计算经过时间的情况下,由于在午夜回绕,可能会遇到困难。这些困难是可以解决的,我所知道的最好的例子是 Linux 内核中 Linus Torvald 的一行代码,它处理计数器环绕。
Keep in mind that the system time is returned as a UTC time (both in the case of GetSystemTimeAsFileTime()
and simply GetSystemTime()
). If you require the local time as configured by the Administrator, then you could use GetLocalTime()
.
请记住,系统时间返回为UTC时间(都在的情况下GetSystemTimeAsFileTime()
,简单地GetSystemTime()
)。如果您需要管理员配置的本地时间,则可以使用GetLocalTime()
.
回答by Jed Smith
To get the time expressed as UTC, use GetSystemTime
in the Win32 API.
要获取以 UTC 表示的时间,请GetSystemTime
在 Win32 API 中使用。
SYSTEMTIME st;
GetSystemTime(&st);
SYSTEMTIME
is documented as having these relevant members:
SYSTEMTIME
被记录为具有以下相关成员:
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
As shf301 helpfully points out below, GetLocalTime
(with the same prototype) will yield a time corrected to the user's current timezone.
正如 shf301 在下面有帮助地指出的那样,GetLocalTime
(使用相同的原型)将产生一个更正为用户当前时区的时间。
You have a few good answers here, depending on what you're after. If you're looking for justtime of day, my answer is the best approach -- if you need solid dates for arithmetic, consider Alex's. There's a lot of ways to skin the time caton Windows, and some of them are more accurate than others (and nobody has mentioned QueryPerformanceCounter
yet).
你在这里有一些很好的答案,这取决于你所追求的。如果你正在寻找的只是一天的时间,我的回答是最好的办法-如果你需要坚实的日期算法,考虑Alex的。有很多方法可以在 Windows 上为时间猫设置皮肤,其中一些方法比其他方法更准确(而且还没有人提到QueryPerformanceCounter
)。
回答by SteveCav
A cut-to-the-chase example of Jed's answer above:
上面 Jed 回答的一个切入正题的例子:
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); }
回答by Alex Martelli
Use GetSystemTime, first; then, if you need that, you can call SystemTimeToFileTimeon the SYSTEMTIME
structure that the former fills for you. A FILETIME
is a 64-bit count of 100-nanosecs intervals since an epoch, and so more suitable for arithmetic; a SYSTEMTIME
is a structure with all the expected fields (year, month, day, hour, etc, down to milliseconds). If you want to know "how many milliseconds have elapsed since midnight", for example, subtracting two FILETIME
structures (one for the current time, one obtained by converting the same SYSTEMTIME
after zeroing out the appropriate fields) and dividing by the appropriate power of ten is probably the simplest available approach.
首先使用GetSystemTime;然后,如果您需要,您可以在前者为您填充的结构上调用SystemTimeToFileTimeSYSTEMTIME
。AFILETIME
是自一个纪元以来 100 纳秒间隔的 64 位计数,因此更适合算术;aSYSTEMTIME
是一个包含所有预期字段(年、月、日、小时等,小到毫秒)的结构。如果你想知道“自午夜以来已经过去了多少毫秒”,例如,将两个FILETIME
结构相减(一个是当前时间,一个是在将SYSTEMTIME
适当的字段归零后转换相同的结构)并除以适当的十的幂是可能是最简单的可用方法。
回答by Ash
Depending on the needs of your application there are six common options. This Dr Dobbs Journal articlewill give you all the information (and more) you need on choosing the best one.
根据您的应用程序的需要,有六种常见选项。这篇Dr Dobbs Journal 文章将为您提供选择最佳产品所需的所有信息(以及更多信息)。
In your specific case, from this article:
在您的具体情况下,从这篇文章:
GetSystemTime() retrieves the current system time and instantiates a SYSTEMTIME structure, which is composed of a number of separate fields including year, month, day, hours, minutes, seconds, and milliseconds.
GetSystemTime() 检索当前系统时间并实例化一个 SYSTEMTIME 结构,该结构由许多单独的字段组成,包括年、月、日、小时、分钟、秒和毫秒。
回答by user1231247
Here is some code that works in Windows which I've used in a Open Watcom C project. It should work in C++ It returns seconds (not milliseconds) using _dos_gettime or gettime
这是我在 Open Watcom C 项目中使用的一些适用于 Windows 的代码。它应该在 C++ 中工作它使用 _dos_gettime 或 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
}