C&C++中的时间函数和时间类

现代标准时间:协调世界时,又称世界统一时间、世界标准时间、国际协调时间。由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。协调世界时是以原子时秒长为基础,在时刻上尽量接近于世界时的一种时间计量系统。

C语言的 time 函数和 localtime 函数 (基于格林威治标准时间(GMT))

#pragma warning(disable : 4996)//disable error C4996

#include <time.h>
int main() {
    time_t t = time(NULL);//获取当前时间句柄, time_t 就是 int64
    tm* ptime = localtime(&t);//将时间句柄转换为时间结构体tm, localtime 以前的函数可能会报 error C4996
    /* 用 localtime_s()
    tm time;
    localtime_s(&time, &t);
    tm* ptime = &time;
    */
    int nYear = ptime->tm_year + 1900;
    int nMonth = ptime->tm_mon + 1;
    int nDay = ptime->tm_mday;
    int nHour = ptime->tm_hour;
    int nMinute = ptime->tm_min;
    int nSecond = ptime->tm_sec;
    printf("%d-%02d-%02d %02d:%02d:%02d", nYear, nMonth, nDay, nHour, nMinute, nSecond);
//  time_t t = time(NULL);
//  char* s = ctime(&t);//"Sat Sep 14 11:06:08 2019\n"

    return 0;
}

 

 

C++的CTime类(MFC中),其实就是对上面的封装。(基于格林威治标准时间(GMT))

#define _AFXDLL
#include <afx.h>

int main() {
    CTime t = CTime::GetCurrentTime();
    int nYear = t.GetYear();
    int nMonth = t.GetMonth();
    int nDay = t.GetDay();
    int nHour = t.GetHour();
    int nMinute = t.GetMinute();
    int nSecond = t.GetSecond(); 
    printf("%d-%02d-%02d %02d:%02d:%02d", nYear, nMonth, nDay, nHour, nMinute, nSecond);
    //或者直接format
    CString s = t.Format("%Y-%m-%d %H:%M:%S");//2019-09-14 10:47:03

    return 0;
}

VC6.0下,在CTime中,年的范围是1970到2038(包含2038)。距1970-1-1 12:0:0 am 也就是2的32次方秒. (当 time_t 是32位的)

在time_t 是 int64 时,CTime类表示日期上限是3000年12月31日,下限是1970年1月1日 12:00:00 AM GMT。

 

2038年问题

 

和21世纪初的千年虫(the Millennium bug)问题类似,32位的Unix操作系统和Linux操作系统时间溢出问题又称为2038年问题(the Year 2038 problem)。如果你想知道什么是2038问题的话,你需要知道一些技术上的东西。这个bug是由用来写Unix/Linux的C语言引起的,C语言中用 time_t 来代表时间和日期,time_t 是整数(int)型的,它用来记载从1970年1月1日到2000年所经历的秒数。

 

这个数据是以32位存储的,第一位是符号位,其余的31位用来存数字,而这31位数字可以存储的最大数字为2147483647。

 

从1970年开始计算,这31位的数字可以表示的秒数最多可以用到2038年01月19日03时14分07秒,当时间到达这个数字的时候系统将会出现问题,到时候数字不会自动增加,而是会变为-2147483648,而这串数字代表的时间是1901年12月13日20时45分52秒,这会导致很多的程序出现问题,甚至崩溃。

 

2038年问题不仅比千年虫更隐蔽,而且比之前千年虫问题更具有破坏力,因为千年虫问题只会导致应用层的程序出现问题,比如信用卡支付系统,或者管理系统。而2038这个bug,将会影响系统最底层的时间控制的功能。

 

要解决这个问题,最简单的方式是扩展Unix时间的长度,用64位数字来表示它。64位二进制数的实际可用位数是63位,最大表示到公历的UTC时间292,277,026,596年12月4日15时30分08秒. 如果那个时候人类文明还存在的话,公元纪年很可能已经因为太难用而被抛弃了. 理想的情况是到2038年,64位系统已经成为主流,从而避免特意去修正这个问题所需要的大量开销。否则,人们就必须把新的64位时间拆分成两部分并分别保存在两个变量里,这是一个麻烦而且效率低下的选择.

 

 

MFC中的 COleDateTime,COleDateTime类处理了从100年1月1日到9999年12月31日的日期。

#define _AFXDLL
#include <afx.h>
#include <afxdisp.h>

int main() {
    COleDateTime t = COleDateTime::GetCurrentTime();
    int nYear = t.GetYear();
    int nMonth = t.GetMonth();
    int nDay = t.GetDay();
    int nHour = t.GetHour();
    int nMinute = t.GetMinute();
    int nSecond = t.GetSecond(); 
    printf("%d-%02d-%02d %02d:%02d:%02d", nYear, nMonth, nDay, nHour, nMinute, nSecond);
    //或者直接format
    CString s = t.Format(_T("%Y-%m-%d %H:%M:%S"));//2019-09-14 10:47:03

    return 0;
}

 

%a: 周的英文缩写形式。
%A: 周的英文全名形式。
%b: 月的英文缩写形式。
%B: 月的英文全名形式。
%c: 完整的日期和时间。
%d: 十进制形式的日期(01-31)。
%H: 24小时制的小时(00-23)。
%I: 12小时制的小时(00-11)。
%j: 十进制表示的一年中的第几天(001-366)。
%m: 月的十进制表示(01-12)。
%M: 十进制表示的分钟(00-59)。
%p: 12小时制的上下午标示(AM/PM)。
%S: 十进制表示的秒(00-59)。
%U: 一年中的第几个星期(00-51),星期日是一周的第一天。
%W: 一年中的第几个星期(00-51),星期一是一周的第一天。
%w: 十进制表示的星期几(0-6)。
%Y: 十进制表示的年。

 

posted @ 2019-09-14 10:30  htj10  阅读(1365)  评论(0编辑  收藏  举报
TOP