C++ time

本文介绍时间处理的基础概念,包括UTC/GMT、Localtime和Calendartime,并详细解释C++中时间相关的数据类型如time_t和struct tm,以及常用的时间处理函数如time、gmtime、localtime等。通过实例演示如何进行时间的获取、转换和格式化。

一、三个概念:

(1)UTC/GMT:Coorainated Universal Time:它是一个标准,最主要的世界时间标准,其以原子时秒长为基础,在时刻上尽量接近于格林尼治平时,也即格林威治标准时间(Greenwich Mean Time,GMT),在大多数场合,UTC与GMT等同(只是GMT不再由科学界精确定义)。
:为描述方便,本文中将UTC与GMT等同。

(2)Local time:指相对于UTC/GMT时间的本地时间(时区转换)。比如,中国内地的时间与UTC的时差为+8,也就是UTC+8。美国是UTC-5。

(3)Calendar time:日历时间,是用“从一个标准时间点到此时的时间经过的秒数”来表示的时间。在计算机中是相对于时间点:1970年1月1日,来算的。

二、主要数据类型、结构及函数头文件:<ctime> (或者 time.h)
(1)types:

time_t:time type,通常为整型值,表示自1970年1月1日00:00到现在所经过的秒数。
typedef long time_t

struct tm:time structure,该结构体包含了日历时间和日期,其中各成员详细信息如下:

1,tm_year是指自1900年后的个数,故要得出真正的年份,还有加上1900(即tm_year + 1900)。2,tm_isdst指夏令时标识符,实行夏令时的时候,tm_isdst为正。不实行夏令时的进候,tm_isdst为0;不了解情况时,tm_isdst()为负。但中国不实行夏令时,即此处应该0.
(2)functions:(以下只挑选了几个有代表性的函数为的是理清思路,更多函数可参考C++手册)

函数名:time
原型:time_t  time (time_t*  timer):
功能:获取当前的日历时间。若 timer 为NULL,则返回日历时间;若timer非NULL则将获取的日历时间存于timer中。

函数名:gmtime:
原型:struct tm*  gmtime (const time_t*  timer);
功能:将time_t类型的日历时间转换为 tm 结构的UTC(GMT)时间。

函数名:localtime
原型:struct tm*  localtime (const  time_t*  timer);
功能:将time_t类型的日历时间转换为 tm 结构的 Local time(本地时间)。

函数名:ctime
原型:char*  ctime (const  time_t*  timer);
功能:将time_t类型的日历时间转换为适合人们阅读(human-readable)的字符串格式的时间。

函数名:mktime
原型:time_t  mktime (const struct tm*  timeptr);
功能:将tm结构体类型的时间转换为 time_t类型的时间

函数名:asctime
原型:char*  asctime (const struct tm*  timeptr);
功能:将tm结构体类型的时间转换为适合人们阅读的字符串格式的时间。


综上,可以发现时间的表示形式不外乎三种:time_t、strcut tm以及string(char*).


三、例子

#include<iostream>
#include<string>
#include<ctime>
using namespace std;
int main()
{
     time_t rawtime = time(NULL);
     cout<<"rawtime:"<<rawtime<<endl;
     struct tm localtm = *localtime(&rawtime);
     struct tm UTCtm = *gmtime(&rawtime);
     cout<<"----------UTC time VS local time-----------"<<endl; 
     cout<<"tm_sec:   "<<localtm.tm_sec<<"          "<<UTCtm.tm_sec<<endl;
     cout<<"tm_min:   "<<localtm.tm_min<<"          "<<UTCtm.tm_min<<endl;
     cout<<"tm_hour:  "<<localtm.tm_hour<<"          "<<UTCtm.tm_hour<<endl;
	 cout<<"tm_mday:  "<<localtm.tm_mday<<"          "<<UTCtm.tm_mday<<endl;
     cout<<"tm_mon:   "<<localtm.tm_mon+1<<"          "<<UTCtm.tm_mon+1<<endl;
	 cout<<"tm_year:  "<<localtm.tm_year+1900<<"        "<<UTCtm.tm_year+1900<<endl;
     cout<<"tm_yday:  "<<localtm.tm_yday<<"         "<<UTCtm.tm_yday<<endl;
     cout<<"tm_isdst: "<<localtm.tm_isdst<<"           "<<UTCtm.tm_isdst<<endl;
     string cstime = asctime(&localtm);
     cout<<"string time:"<<cstime<<endl;
     time_t makeLocal = mktime(&localtm);
     cout<<"mktime (hours)local: "<<makeLocal/3600<<endl;
     time_t makeUTC = mktime(&UTCtm);
     cout<<"mktime (hours)UTC: "<<makeUTC/3600<<endl;
     return 0;
}

输出结果


注:由结果可知,local time(UTC+8)比UTC要大8个小时,而其他member均一样。

四、关于localtime的返回值的内存问题:

在执行localtime(或者是gmtime或者是mktime等)时,有一个小问题。注意到代码中的:

struct tm localtm =*localtime(&rawtime);
struct tm UTCtm = *gmtime(&rawtime);

当我们写成:
struct tm* localtmptr = localtime(&rawtime);
struct tm*UTCtmptr = gmtime(&rawtime);
则会出现问题,运行结果会发现又localtime和gmtime得出的时间值时一样的,它们之间并不相差8个小时。

为什么会这样呢?

通过man localtime命令,可以发现一些细节:


即 localtime(或者是gmtime或者是mktime)等,它们的返回值都是指向一个共享的静态存储区,该块内存可能会被后面的时间函数重写。故 若有时间函数连续出现时,应该直接返回该内存,而不是指向该内存的指针。
这样一来,每一个时间函数都会从静态存储区把自己的时间拷贝出来,存入自己的内存区。

C++ 中获取当前时间,可以使用多种方法。以下是几种常见的实现方式: ### 1. 使用 `<ctime>` 获取系统时间(秒级) 通过标准库 `<ctime>` 可以获取当前时间并将其转换为可读格式: ```cpp #include <iostream> #include <ctime> int main() { // 获取当前时间(秒级) time_t now_time = time(NULL); // 转换为本地时间结构体 tm* t_tm = localtime(&now_time); // 输出年月日、时分秒 std::cout << "Current Time: " << t_tm->tm_year + 1900 << "-" << t_tm->tm_mon + 1 << "-" << t_tm->tm_mday << " " << t_tm->tm_hour << ":" << t_tm->tm_min << ":" << t_tm->tm_sec << std::endl; } ``` ### 2. 使用 Windows API 获取毫秒级时间 如果需要更精确的时间(例如毫秒),可以使用 Windows 提供的 `GetTickCount()` 函数来获取从系统启动以来经过的毫秒数: ```cpp #include <windows.h> #include <iostream> int main() { DWORD time_start = GetTickCount(); // 获取开始时间 Sleep(3000); // 模拟延迟 DWORD time_end = GetTickCount(); // 获取结束时间 std::cout << "Elapsed Time: " << (time_end - time_start) << " ms" << std::endl; return 0; } ``` ### 3. 使用 C++11 的 `<chrono>` 库获取高精度时间 C++11 引入了 `<chrono>` 标准库,支持更高精度的时间操作,并且具有更好的可移植性: ```cpp #include <iostream> #include <chrono> #include <ctime> int main() { // 获取当前时间点 auto now = std::chrono::system_clock::now(); // 转换为 time_t 时间戳 time_t now_time = std::chrono::system_clock::to_time_t(now); // 转换为本地时间 tm* t_tm = localtime(&now_time); std::cout << "Current Time: " << t_tm->tm_year + 1900 << "-" << t_tm->tm_mon + 1 << "-" << t_tm->tm_mday << " " << t_tm->tm_hour << ":" << t_tm->tm_min << ":" << t_tm->tm_sec << std::endl; return 0; } ``` ### 4. 使用 MFC 类 `CTime` 获取当前时间 如果你在使用 Microsoft Foundation Classes (MFC),可以通过 `CTime::GetCurrentTime()` 获取当前时间: ```cpp #include <atltime.h> #include <stdio.h> int main() { CTime time = CTime::GetCurrentTime(); printf("%04d/%02d/%02d %02d:%02d:%02d\n", time.GetYear(), time.GetMonth(), time.GetDay(), time.GetHour(), time.GetMinute(), time.GetSecond()); return 0; } ``` 以上方法涵盖了不同场景下的时间获取需求,包括秒级、毫秒级以及基于现代 C++ 的实现[^2]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值