前言

在C++日志系统中,打印时间是必不可少的一个操作。

在 Linux C 语言编程中,有两种时间表示方式:

  • 一种是日历时间(calendar time),用于表示自纪元(Epoch)以来的秒数,他可以转换成我们日常看到的时间。

  • 一种是处理器时间(processor time),用于表示程序在 CPU 上执行的时间。本文主要关注日历时间的处理。

时间戳的概念

时间戳是一种用数字表示时间的方式。它是一个简单的计数器,记录了某个特定事件发生时的时间和日期。

你可以把时间戳看作一个独一无二的数字标记,表示了某个时刻的时间。这个数字通常是从某个参考点(通常是纪元)开始不断增加的。

时间戳可以精确到秒、毫秒甚至更小的单位,取决于使用的系统和编程语言。使用时间戳,我们可以轻松地对事件按照时间顺序进行排序和比较,而不用担心日期格式、时区等复杂的问题。

时间戳在计算机科学和软件开发中非常有用。它可以用来记录事件发生的顺序、计算时间差、创建时间戳序列、做数据分析等等。许多操作系统和编程语言都提供了用于获取和处理时间戳的函数和工具,使我们可以方便地使用它们。

简而言之,时间戳就是用数字来表示特定时刻的时间和日期,方便我们在计算机中处理和比较时间

时间函数

time()

time()函数是 C 和 C++ 中最基本的时间函数,它返回自 1970 年 1 月 1 日起的秒数。其函数原型如下:

1
time_t time(time_t *tloc);

参数的作用:

  • 当参数为NULL时:time_t这个整型值通过返回值返回。
  • 当参数不为NULL时:time_t我们需要的这个整型值通过参数指针得到。

time_t类型

  • time_t是一个用于表示时间的数据类型,它在 C 语言中广泛使用。可以把它看作是一个整数类型,用于存储时间戳

使用示例

1
2
3
4
5
6
7
8
#include <stdio.h>
#include <time.h>
int main() {
time_t current_time;
time(&current_time);
printf("当前时间为: %lld\n", (long long)current_time);
return 0;
}

下面也是可以的

1
2
3
4
5
6
7
8
#include <stdio.h>
#include <time.h>
int main() {
time_t current_time;
current_time=time(NULL);
printf("当前时间为: %lld\n", (long long)current_time);
return 0;
}

gettimeofday()

gettimeofday() 这个函数在 Unix 和 Linux 系统中常用,它可以获取到微秒级别的时间,更加精确。

函数原型:

1
2
#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <string.h>
#include <sys/time.h>

int main()
{
struct timeval tv;

gettimeofday(&tv, NULL);

printf("tv_sec: %d\n", tv.tv_sec);
printf("tv_usec: %d\n", tv.tv_usec);

return 0;
}

localtime()

localtime() 函数的功能是将 time_t 类型的时间转换为一个 tm 结构体类型的时间。

localtime() 函数的原型如下:

1
struct tm* localtime(const time_t* timer);
  • 参数

timer:要转换的时间。

  • 返回值

返回一个指向 tm 结构体变量的指针,该变量存储了当前时间的各个组成部分。

tm结构体

1
2
3
4
5
6
7
8
9
10
11
12
struct tm
{
int tm_sec; /* Seconds (0-60) */
int tm_min; /* Minutes (0-59) */
int tm_hour; /* Hours (0-23) */
int tm_mday; /* Day of the month (1-31) */
int tm_mon; /* Month (0-11) */
int tm_year; /* Year - 1900 */
int tm_wday; /* Day of the week (0-6, Sunday = 0) */
int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */
int tm_isdst; /* Daylight saving time */
};

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <time.h>

int main() {
time_t current_time;
struct tm* local_time;

// 获取当前时间
current_time = time(NULL);

// 转换为本地时间结构体
local_time = localtime(&current_time);

// 检查是否转换成功
if (local_time != NULL) {
printf("%04d-%02d-%02d %02d:%02d:%02d\n",
local_time->tm_year + 1900, // 年份
local_time->tm_mon + 1, // 月份
local_time->tm_mday, // 日
local_time->tm_hour, // 小时
local_time->tm_min, // 分钟
local_time->tm_sec // 秒
);
} else {
printf("时间转换失败\n");
}
return 0;
}
1
2024-04-30 18:54:30

Note:

localtime函数不是线程安全的。在多线程应用里面,应该用localtime_r函数替代localtime函数,因为localtime_r是线程安全的。

gmtime()

类似 localtime(),但返回的是格林尼治标准时间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <ctime>
#include <iostream>

int main() {
// 获取当前系统时间
std::time_t current_time = std::time(nullptr);

// 使用 gmtime 转换为格林尼治标准时间
std::tm* gm_time = std::gmtime(&current_time);

// 输出时间
std::cout << "UTC time: " << gm_time->tm_hour << ":"
<< gm_time->tm_min << ":"
<< gm_time->tm_sec << "\n";

return 0;
}

strftime()

strftime() 函数的作用是按照指定的格式将时间结构体转换为字符串表示。

函数原型如下:

1
size_t strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr);

strftime参数解析:

  • s:一个指向字符数组的指针,用于存储格式化后的时间字符串。这个字符数组必须具有足够的空间来存储生成的字符串。

  • maxsize:表示存储时间字符串的字符数组的最大长度。这是为了避免溢出。

  • format:一个指向格式化字符串的指针,用于定义时间字符串的输出格式。格式字符串包含特定的格式占位符,如 %Y 表示年份,%m 表示月份等。

  • timeptr:一个指向 struct tm 结构体的指针,其中包含了要格式化的时间信息。这个结构体存储了年、月、日、时、分、秒等时间字段的值。

strftime返回值解析

  • 函数 strftime() 的返回值是一个 size_t 类型的整数,表示成功写入目标字符串 s 的字符数(不包括末尾的空字符)。

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <time.h>

int main() {
time_t current_time;
time(&current_time);

struct tm *local_t = localtime(&current_time);
char time_str[64];

strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", local_t);
printf("当前时间为: %s\n", time_str);

return 0;
}
1
当前时间为: 2024-04-30 19:05:43

chrono库

这是 C++11 中引入的新的时间库,可以方便地获取高精度时间,并进行时间的算术运算。

参考资料