zoukankan      html  css  js  c++  java
  • VC++时间函数总结

    1基本概念    1

    1.1 基本概念    1

    1.2 时间表示法    2

    2 Win32 API    3

    2.1 获取    3

    2.1.1 时间间隔    3

    2.1.2 时刻    3

    2.1.3 时区    3

    2.1.4 时区信息    5

    2.2 设置    6

    2.2.1 时刻    6

    2.2.2 时区    7

    2.2.3 时间基准    7

    2.3 比较    7

    2.4 转换    7

    2.4.1 DOS时间与FILETIME转换    8

    2.4.2 SYSTEMTIMEFILETIME转换    8

    2.4.3 本地时间与UTC时间转换    8

    3 C运行时库函数    9

    3.1 获取    9

    3.1.1 时间间隔    9

    3.1.2 时刻    9

    3.2 设置    10

    3.2.1 时刻    10

    3.2.2 时区    10

    3.3 比较    10

    3.4 转换    11

    3.4.1 time_tstruct tm    11

    3.5 格式化    12

    3.5.1 asctime    12

    3.5.2 ctime    12

    3.5.3 strftime    12

    4 MFC    13

    1基本概念

    1.1 基本概念

    GMTGreenwich Mean Time)是格林尼治标准时间。它是通过观测太阳来确定时间的,即力学时。力学时的精确度不是很高,所以它被协调世界时(Coordinate Universal Time,简称UTC)所取代。UTC采用原子钟计时,所以它的精确度很高。Windows中,GMTUTC没有区别,被统称为系统时间(System Time)。

    标准时(Standard Time)等于UTC时间加上时差,如:中国的时区为+8:00,北京时间就是UTC时间加上8小时。

    某些国家在夏季还将执行夏令时,也就是日光节能时(Daylight Saving Time,简称DST)。就是在夏季将时钟拨快1小时,早起早睡充分利用太阳光以达到节约能源的目的。UTC时间、标准时、夏令时的关系请参考下面两张图形:

    图1.1 北半球一年内的时间

    图1.2 南半球一年内的时间

    Windows中,标准时和夏令时被统称为本地时间(Local Time)。本地时间有时会有歧义,如图1.1和图1.2中的绿色部分,它所表示的本地时间是标准时还是夏令时?

    1.2 时间表示法

    VC中对时间的表示一般有两种方法。一种是人们熟知的年、月、日、时、分、秒,如:SYSTEMTIMEstruct tm,这种表示方法被称之为broken-down time

    另一种是从基准时刻到当前时刻的时间间隔,如:time_t表示197011日到当前时刻的秒数,称这种表示方法为calendar time。类似的还有FILETIME,它其实就是一个__int64,表示160111日到当前时刻的时间间隔(单位10-7 秒,即100纳秒,万分之一毫秒)。

    2 Win32 API

    2.1 获取

    2.1.1 时间间隔

    GetTickCountGetTickCount64返回启动Windows后到现在的毫秒数。GetTickCount返回一个DWORD,最大为0xFFFFFFFF秒,约为49.71天。也就是说连续运行Windows系统 50 天后,GetTickCount会从零开始计时。

    GetTickCount64返回一个unsigned __int64,最大为0xFFFFFFFFFFFFFFFF秒,约为 5.8亿年。再也不用担心计时重新归零的问题了。

    2.1.2 时刻

    GetSystemTime用于获取毫秒级UTC时刻。

    GetSystemTimeAsFileTime用于获取10-7 秒级的UTC时刻。

    GetLocalTime用于获取本地时刻。要想知道这个时刻为标准时还是夏令时请通过GetTimeZoneInformation的返回值进行判断:返回TIME_ZONE_ID_DAYLIGHT表示夏令时,返回TIME_ZONE_ID_STANDARDTIME_ZONE_ID_UNKNOWN表示标准时。TIME_ZONE_ID_UNKNOWN还表明了系统未启用夏令时。

    GetFileTime用于获取打开文件(或文件夹)的UTC时刻。为了获取未打开文件的UTC时刻,请使用FindFirstFile函数。

    2.1.3 时区

    GetTimeZoneInformation函数可以获取时区信息,包括:时差、标准时偏差、夏令时偏差、夏令时开始时刻(标准时)、夏令时结束时刻(夏令时)。它获取的时区信息保存在结构TIME_ZONE_INFORMATION内:

    typedef struct _TIME_ZONE_INFORMATION { // tzi

    LONG                Bias;

    WCHAR            StandardName[32];

    SYSTEMTIME        StandardDate;

    LONG                StandardBias;

    WCHAR            DaylightName[32];

    SYSTEMTIME        DaylightDate;

    LONG                DaylightBias;

    } TIME_ZONE_INFORMATION;

    这个结构各个成员变量的含义请参考下图:

    图2.1 时区信息

    Bias是时区时差的相反数,StandardBias为标准时偏差(没发现不为零的情况),DaylightBias为夏令时偏差(一般为-60),它们的单位都是分钟。UTC与标准时、夏令时的转换公式如下:

    UTC=标准时 + Bias + StandardBias

    UTC=夏令时 + Bias + DaylightBias

    DaylightDate是夏令时的开始时刻,它是标准时。DaylightDate 各个成员变量的含义如下:

    成员变量

    示例数值

    wYear; 

    年,一般为零

    0 

    wMonth; 

    月。0表示没有夏令时

    4 

    wDayOfWeek; 

    06分别表示星期日至星期六

    1 

    wDay; 

    第几个,范围[1,5]5表示最后一个。

    0 

    wHour; 

    2 

    wMinute; 

    0 

    wSecond; 

    0 

    wMilliseconds; 

    毫秒

    0 

    以上表为例,夏令时的开始时刻为每年4月的第1个星期日的2:00:00.000

    StandardDate是夏令时的结束时刻,它是夏令时。StandardDate各个成员变量的含义请参考上表。

    注意:对于北半球而言,DaylightDate小于StandardDate,但是到了南半球则正好相反。

    因为夏令时的开始、结束时间可能是变化的,自Vista后引入了下面两个函数:

    GetTimeZoneInformationForYear

    GetDynamicTimeZoneInformation

    2.1.4 时区信息

    时区信息全部存放在注册表里:

    对于Windows 98而言,存放在如下位置:

    HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsCurrentVersionTime Zones

    对于Windows NT而言,存放在如下位置:

    HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionTime Zones

    对于Windows CE而言,存放在如下位置:

    HKEY_LOCAL_MACHINETime Zones

    如:修改WinCE时区为北京时间:

    [HKEY_LOCAL_MACHINETime Zones]
    "Default"="China Standard Time"

    注册表里的二进制数据TZI,其结构如下:

    #pragma pack(push,1)

    class TZI

    {

    LONG        Bias;        //时差,单位:分钟

    LONG        StandardBias;    //标准时差,单位:分钟

    LONG        DaylightBias;    //夏令时时差,单位:分钟

    SYSTEMTIME    StandardDate;    //夏令时结束时刻

    SYSTEMTIME    DaylightDate;    //夏令时开始时刻

    };

    #pragma pack(pop)

    2.2 设置

    2.2.1 时刻

    SetSystemTime用于设置WindowsUTC时刻。

    SetLocalTime用于设置Windows的本地时刻。如果Windows启用了夏令时,有时会出现意想不到地后果。举例说明:假定系统时区为-8:00,并启用了夏令时。现在调用代码 SetLocalTime(2000.07.07 10:11:12),将会有两种不同的结果:

    如果当前系统正处于夏令时,首先把2000.07.07 10:11:12转换为UTC时刻,即2000.07.07 10:11:12+7:00=2000.07.07 17:11:12,然后调用SetSystemTime(2000.07.07 17:11:12)。因为2000.07.07 17:11:12处于夏令时,所以最终的本地时刻为2000.07.07 17:11:127:00=2000.07.07 10:11:12,这是一个令人满意的结果。

    如果当前系统处于标准时,首先把2000.07.07 10:11:12转换为UTC时刻,即2000.07.07 10:11:12+8:00=2000.07.07 18:11:12,然后调用SetSystemTime(2000.07.07 18:11:12)。因为2000.07.07 18:11:12处于夏令时,所以最终的本地时刻为2000.07.07 18:11:127:00=2000.07.07 11:11:12,这个结果实在令人不可思议!

    SetFileTime用于修改某个打开文件(或文件夹)的UTC时刻。不打开文件,如何修改其时刻?

    2.2.2 时区

    SetTimeZoneInformation

    SetDynamicTimeZoneInformation

    2.2.3 时间基准

    将计算机的BIOS时间当作本地时间

    REGEDIT4

     

    [HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlTimeZoneInformation]

    "RealTimeIsUniversal"=dword:00000000

    将计算机的BIOS时间当作UTC时间

    REGEDIT4

     

    [HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlTimeZoneInformation]

    "RealTimeIsUniversal"=dword:00000001

    2.3 比较

    CompareFileTime

    2.4 转换

    2.4.1 DOS时间与FILETIME转换

    DosDateTimeToFileTime

    FileTimeToDosDateTime

    2.4.2 SYSTEMTIMEFILETIME转换

    FileTimeToSystemTime

    SystemTimeToFileTime

    2.4.3 本地时间与UTC时间转换

    FileTimeToLocalFileTime

    LocalFileTimeToFileTime

    如果Windows启用了夏令时,上面两个函数是无法正常工作的。如假定系统时区为-8:00,并启用了夏令时。则将UTC时刻转换为本地时刻将用到如下两个公式:

    夏令时=UTC7:00

    标准时=UTC8:00

    正确的做法是:首先根据UTC时刻判断本地时刻是夏令时还是标准时,然后选择公式进行计算。但上面两个函数不是这么工作的,它们根据Windows当前处于夏令时还是标准时选择公式进行计算。

    SystemTimeToTzSpecificLocalTime

    TzSpecificLocalTimeToSystemTime

     

    3 C运行时库函数

    3.1 获取

    3.1.1 时间间隔

    3.1.1.1 clock

    原型:clock_t clock( void )

    功能:返回进程已经运行的时间,单位:1 / CLOCKS_PER_SEC 秒。

    注意:clock_t其实就是long

    3.1.2 时刻

    3.1.2.1 time, _time32, _time64

    原型:time_t time( time_t *timer );

    功能:返回当前UTC时刻。

    说明:

    1、返回值表示自 1970 1 1 日到当前时刻的秒数;

    2、在VC++6.0中,没有_time32, _time64time_t相当于long。因此,time_t最多只能表示到 2038-01-19 03:14:07

    3、在VC++2005中,_time32的返回值为long_time64的返回值为__int64。至于time的返回值则要取决于是否定义了宏_USE_32BIT_TIME_T,定义了就是long,未定义就是__int64

    3.1.2.2 _ftime

    原型:void _ftime( struct _timeb *timeptr );

    功能:获得当前UTC时刻、时差、是否为夏令时等信息。

    说明:

    1、与time函数相比,_ftime获得的时间精度更高(包含毫秒),信息更加丰富,如:包含时差信息。具体的请参考_timeb结构:

    struct _timeb

    {

    time_t time;            //UTC时刻

    unsigned short millitm;    //毫秒

    short timezone;         //时差= UTC时刻 -本地时刻,单位:分钟

    short dstflag;            //非零表示目前正处于夏令时

    };

    3.1.2.3 _stat_fstat

    用于获取文件时间

    3.1.2.4 _strdate

    获取当前UTC日期至一个字符串内

    3.1.2.5 _strtime

    获取当前UTC时间至一个字符串内

    3.2 设置

    3.2.1 时刻

    _utime_futime用于修改文件的访问、修改时刻,它们的不同之处在于指定文件的方式不同:前者通过路径名指定文件,后者通过文件句柄指定文件。

    3.2.2 时区

    请使用 _tzset 函数

    3.3 比较

    请使用 difftime 函数

    3.4 转换

    3.4.1 time_tstruct tm

    struct tm 结构如下:

    struct tm

    {

    int tm_sec;    //[0,59]

    int tm_min;    //[0,59]

    int tm_hour;    //[0,23]

    int tm_mday;    //[1,31]

    int tm_mon;    //月减去一[0,11]

    int tm_year;    //年减去1900

    int tm_wday;    //星期[0,6]0表示周日

    int tm_yday;    //年积日[0,365]

    int tm_isdst;    //正数表示为夏令时,0表示标准时,小于零表示未知

    };

    它既可以表示UTC时刻,也可以表示本地时刻。表示本地时刻时,通过tm_isdst可以明确指定该时刻为标准时刻还是夏令时刻。

    3.4.1.1 time_tUTC时刻)转换为 struct tmUTC时刻)

    请使用 gmtime 函数

    3.4.1.2 struct tmUTC时刻)转换为 time_tUTC时刻)

    请使用 _mkgmtime 函数

    3.4.1.3 time_tUTC时刻)转换为 struct tm(本地时刻)

    请使用 localtime 函数

    3.4.1.4 struct tm(本地时刻)转换为 time_tUTC时刻)

    请使用 mktime 函数

    原型:time_t mktime( struct tm *timeptr );

    说明:

    1timeptr-> tm_isdst为正数(一般为1)时,表示将夏令时转换为UTC时刻;

    2timeptr-> tm_isdst为零时,表示将标准时转换为UTC时刻;

    3timeptr-> tm_isdst为负数(一般为-1)时,函数将自动判断本地时刻是夏令时还是标准时,然后再转换为UTC时刻。注意:夏令时、标准时的判断并不能完全正确;

    3.5 格式化

    3.5.1 asctime

    struct tm转换为字符串格式的时间

    3.5.2 ctime

    time_t转换为字符串格式的时间

    3.5.3 strftime

    struct tm格式化输出为字符串

     

    4 MFC

    MFC中,CTimeCOleDateTime可用于处理时间。它们的异同:

    1CTime封装的是C函数,COleDateTime封装的是Win32 API

    2CTime可以处理夏令时,COleDateTime没有此功能;

    3CTime以一个整数表示时刻,COleDateTime以一个double表示时刻。它们都只能精确到秒。

    4VC++6.0CTime使用long表示时刻,时间范围为 197011日至2038118日。自VC++2002以后,CTime使用__int64表示时刻,时间范围为197011 12:00:0030001231日。

    COleDateTime 表示的时间范围:10011日至99991231日。

  • 相关阅读:
    bzoj 3930: [CQOI2015]选数
    bzoj 2301: [HAOI2011]Problem b
    HDU 1695 GCD
    2017ACM/ICPC广西邀请赛-重现赛 1007.Duizi and Shunzi
    2017ACM/ICPC广西邀请赛-重现赛 1010.Query on A Tree
    2017ACM/ICPC广西邀请赛-重现赛 1004.Covering
    P3501 [POI2010]ANT-Antisymmetry
    P1171 售货员的难题
    P3385 【模板】负环
    P1659 [国家集训队]拉拉队排练
  • 原文地址:https://www.cnblogs.com/hanford/p/6028005.html
Copyright © 2011-2022 走看看