UNIX操作系统根据计算机产生的年代把1970年1月1日作为UNIX的纪元时间,1970年1月1日是时间的中间点,将从1970年1月1日起经过的秒数用一个整数存放。
一、time_t别名
time_t用于表示时间类型,它是一个long类型的别名,在<time.h>文件中定义,表示从1970年1月1日0时0分0秒到现在的秒数。
typedef long time_t;
二、time()库函数
time()库函数用于获取操作系统的当前时间。
包含头文件:<time.h>
声明:
time_t time(time_t *tloc);
有两种调用方法:
time_t now=time(0); // 将空地址传递给time()函数,并将time()返回值赋给变量now。
或
time_t now; time(&now); // 将变量now的地址作为参数传递给time()函数。
三、tm结构体
time_t是一个长整数,不符合人类的使用习惯,需要转换成tm结构体,tm结构体在<time.h>中声明,如下: 2022-10-01 15:30:25 Oct 1,2022 15:30:25
struct tm
{
int tm_year; // 年份:其值等于实际年份减去1900
int tm_mon; // 月份:取值区间为[0,11],其中0代表一月,11代表12月
int tm_mday; // 日期:一个月中的日期,取值区间为[1,31]
int tm_hour; // 时:取值区间为[0,23]
int tm_min; // 分:取值区间为[0,59]
int tm_sec; // 秒:取值区间为[0,59]
int tm_wday; // 星期:取值区间为[0,6],其中0代表星期天,6代表星期六
int tm_yday; // 从每年的1月1日开始算起的天数:取值区间为[0,365]
int tm_isdst; // 夏令时标识符,该字段意义不大
};
四、localtime()库函数
localtime()函数用于把time_t表示的时间转换为tm结构体表示的时间。
localtime()函数不是线程安全的,localtime_r()是线程安全的。
包含头文件:<time.h>
函数声明:
struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);
示例:
#include <iostream>
#include <time.h> // 时间操作的头文件。
using namespace std;
int main()
{
time_t now=time(0); // 获取当前时间,存放在now中。
cout << "now=" << now << endl; // 显示当前时间,1970年1月1日到现在的秒数。
tm tmnow;
localtime_r(&now,&tmnow); // 把整数的时间转换成tm结构体。
// 根据tm结构体拼接成中国人习惯的字符串格式。
string stime = to_string(tmnow.tm_year+1900)+"-"
+ to_string(tmnow.tm_mon+1)+"-"
+ to_string(tmnow.tm_mday)+" "
+ to_string(tmnow.tm_hour)+":"
+ to_string(tmnow.tm_min)+":"
+ to_string(tmnow.tm_sec);
cout << "stime=" << stime << endl;
}
五、mktime()库函数
mktime()函数的功能与localtime()函数相反,用于把tm结构体时间转换为time_t时间。
包含头文件:<time.h>
函数声明:
time_t mktime(struct tm *tm);
该函数主要用于时间的运算,例如:把2022-03-01 00:00:25加30分钟。
思路:1)解析字符串格式的时间,转换成tm结构体;2)用mktime()函数把tm结构体转换成time_t时间;3)把time_t时间加30*60秒;4)用localtime_r()函数把time_t时间转换成tm结构体;5)把tm结构体转换成字符串。
六、gettimeofday()库函数
用于获取1970年1月1日到现在的秒和当前秒中已逝去的微秒数,可以用于程序的计时。
包含头文件:<sys/time.h>
函数声明:
int gettimeofday(struct timeval *tv, struct timezone *tz);
struct timeval {
time_t tv_sec; /* 1970-1-1到现在的秒数 */
suseconds_t tv_usec; /* 当前秒中,已逝去的微秒数 */
};
struct timezone { /* 在实际开发中,派不上用场 */
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of DST correction */
};
示例:
#include <iostream>
#include <sys/time.h> // gettimeofday()需要的头文件。
using namespace std;
int main()
{
timeval start,end;
gettimeofday(&start, 0 ); // 计时开始。
for (int ii=0;ii<1000000000;ii++)
;
gettimeofday(&end, 0 ); // 计时结束。
// 计算消耗的时长。
timeval tv;
tv.tv_usec=end.tv_usec-start.tv_usec;
tv.tv_sec=end.tv_sec-start.tv_sec;
if (tv.tv_usec<0)
{
tv.tv_usec=1000000-tv.tv_usec;
tv.tv_sec--;
}
cout << "耗时:" << tv.tv_sec << "秒和" << tv.tv_usec << "微秒。\n";
}
七、程序睡眠
如果需要把程序挂起一段时间,可以使用sleep()和usleep()两个库函数。
包含头文件:<unistd.h>
函数声明:
unsigned int sleep(unsigned int seconds);
int usleep(useconds_t usec);
下面的示例代码展示了如何使用 C++ 中的 time()
和 localtime_r()
函数来获取当前时间,并将其转换成易于阅读的 tm
结构体格式。这段代码演示了如何从 UNIX 时间戳转换为更具人类可读性的日期和时间格式。
#include <iostream>
#include <ctime> // 包含 time() 和 localtime_r() 需要的头文件
using namespace std;
int main()
{
time_t now = time(0); // 获取当前时间,存储在 now 中
cout << "当前时间戳(秒): " << now << endl; // 显示自1970年1月1日起的秒数
tm tm_now; // 创建 tm 结构体实例
localtime_r(&now, &tm_now); // 安全地将 time_t 时间转换成 tm 结构体
// 根据 tm 结构体拼接成中国人习惯的字符串格式
cout << "当前时间为: ";
cout << tm_now.tm_year + 1900 << "-" // 年份,tm_year 是从1900年开始的年数
<< tm_now.tm_mon + 1 << "-" // 月份,tm_mon 是从0开始的月数
<< tm_now.tm_mday << " " // 日期
<< tm_now.tm_hour << ":" // 小时
<< tm_now.tm_min << ":" // 分钟
<< tm_now.tm_sec << endl; // 秒
return 0;
}
在这段代码中:
time(0)
获取当前的 UNIX 时间戳,即从1970年1月1日0时0分0秒至今的秒数。localtime_r(&now, &tm_now)
是一个线程安全的函数,用于将time_t
类型的时间转换为tm
结构体。这个函数比localtime()
更推荐在多线程环境中使用,以避免潜在的数据竞争。- 输出的时间格式是
年-月-日 时:分:秒
,更符合日常使用习惯。
这个示例安全且有效地展示了如何操作和显示系统时间,使之易于理解和使用。