C 时间日期库
C 语言提供了 time.h
头文件来处理日期和时间。这个库包含了处理时间的函数和类型定义。
重要的时间类型
日历时间 time_t
time_t
是一个用于存储时间的基本类型,通常是一个长整型,表示从 1970 年 1 月 1 日 00:00:00 UTC(称为 UNIX 纪元)开始经过的秒数。
分解时间 struct tm
struct tm
是一个用于保存日期和时间信息的结构体,包含以下成员:
c
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,0 表示一月)
int tm_year; // 年 (从 1900 年开始的年数)
int tm_wday; // 星期几 (0-6,0 表示星期日)
int tm_yday; // 一年中的第几天 (0-365)
int tm_isdst; // 夏令时标志
};
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
常用时间函数
获取当前时间
c
time_t time(time_t* timer);
1
这个函数返回当前的系统时间。
时间转换函数
c
struct tm* localtime(const time_t* timer); // 将 time_t 转换为本地时间
struct tm* gmtime(const time_t* timer); // 将 time_t 转换为 UTC 时间
time_t mktime(struct tm* timeptr); // 将 struct tm 转换为 time_t
1
2
3
2
3
格式化时间字符串
c
[[deprecated]] char* ctime(const time_t* timer); // 将 time_t 转换为字符串
[[deprecated]] char* asctime(const struct tm* timeptr); // 将 struct tm 转换为字符串
size_t strftime(char* str, size_t maxsize, const char* format, const struct tm* timeptr); // 格式化时间字符串
1
2
3
4
2
3
4
使用示例
c
#include <stdio.h>
#include <time.h>
int main() {
// 获取当前时间
time_t now;
time(&now);
// 转换为本地时间
struct tm *local = localtime(&now);
// 使用 strftime 格式化输出
char str[80];
strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", local);
printf("当前时间:%s\n", str);
// 使用 ctime 直接输出
// printf("ctime 输出:%s", ctime(&now));
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
可重入 (Reentrant) 的时间函数
ctime()
、asctime()
、localtime()
、gmtime()
函数都不是线程安全的,因为它们使用了静态缓冲区来存储结果。如果在多线程环境中使用,可能会导致数据竞争和不一致的结果。
为了避免这个问题,C 标准库对于 localtime()
和 gmtime()
提供了可重入的版本,它们使用动态分配的内存来存储结果。
c
char* localtime_r(const time_t* timer, char* buf);
char* gmtime_r(const time_t* timeptr, char* buf);
1
2
2
至于 ctime()
和 asctime()
函数:C 标准库很早就提供了可重入的函数 strftime()
,可以作为这两个函数的上位替代。这两个函数在 C23 中已被弃用。
c
#include <stdio.h>
#include <time.h>
int main(void) {
char buffer[32];
time_t now;
struct tm time_info;
time(&now);
localtime_r(&now, &time_info);
// asctime 格式:"Www Mmm dd hh:mm:ss yyyy\n"
// strftime 格式字符串:"%a %b %d %H:%M:%S %Y\n"
strftime(buffer, sizeof(buffer), "%a %b %d %H:%M:%S %Y\n", &time_info);
printf("用 strftime 实现 asctime 的功能:\n");
printf("%s", buffer);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
计时函数
CPU 时间 clock()
宏 CLOCKS_PER_SEC
高精度时间测量函数
C 语言中提供了一种结构体 struct timespec
,用于表示高精度(精确到纳秒的)时间。
c
struct timespec {
time_t tv_sec; // 秒
long tv_nsec; // 纳秒
};
1
2
3
4
2
3
4
获取高精度当前时间
获取时钟分辨率
时间计算
计算时间差
c
double difftime(time_t time2, time_t time1); // 返回两个时间之间的秒数差
1
时间操作示例
c
#include <stdio.h>
#include <time.h>
int main() {
time_t start, end;
time(&start);
// 执行一些操作
time(&end);
double diff = difftime(end, start);
printf("耗时:%f 秒\n", diff);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
习题
[1.3] 实现
time_duration
结构体,并实现以下操作:struct time_duration duration(time_t, time_t)
;time_t post(time_t, const struct time_duration *)
;time_t pre(time_t, const struct time_duration *)
;time_duration
之间的加法和减法;time_duration
与int
之间的乘法;
[4.6**] 实现
struct tm strptime(const char* str, const char* format)
函数,用于从一个字符串当中按照特定格式读取时间信息。[2.3] 实现
int days_between(int year1, int month1, int day1, int year2, int month2, int day2)
函数,返回两个日期之间的天数。