1 UTC 时间与本地时间
1.1 UTC 时间
- 定义:UTC(Coordinated Universal Time,协调世界时)是全球统一的时间标准,以原子钟的高精度计时为基础,独立于地球自转。
- 特点:
- 不受地理位置或时区影响,是全球各时区统一参考的时间基准。
- 通过引入闰秒(每年最多增加或减少 1 秒)进行调整,以补偿地球自转速度的微小变化。
- 确保与基于地球自转的天文时间(UT1)之间的偏差不超过 0.9 秒。
- 示例:2025-05-20 17:20:00 UTC 表示全球统一的时间点。
1.2 本地时间
- 定义:本地时间(Local Time) 是指将协调世界时(UTC)根据所在时区的偏移量进行调整后的时间,用于满足日常生活中对时间显示和使用的需求。
- 时区(Time Zone):
- 全球被划分为 24 个主要时区,相邻时区之间通常相差 1 小时。
- 部分国家或地区采用 30 分钟或 45 分钟 的非整点时区偏移,如印度(UTC+5:30)、尼泊尔(UTC+5:45)。
- 时区通常以 UTC+X 或 UTC−X 的形式表示:
- UTC+8(如北京时间)表示比 UTC 快 8 小时。
- UTC−5(如美国东部标准时间)表示比 UTC 慢 5 小时。
- 夏令时(Daylight Saving Time, DST):
- 某些地区在夏季实行夏令时,通常将时间提前 1 小时(把钟表的时间从当前时间向后调快 1 小时),以更好地利用自然光照,节约能源。
- 夏令时的开始与结束时间因国家和地区而异,可能导致本地时间与 UTC 的偏移在一年中发生临时变化。
- 示例:假设当前 UTC 时间为:2025-05-20 12:00:00
- 北京(UTC+8) 的本地时间为:2025-05-20 20:00:00
- 纽约(UTC−5,非夏令时期间) 的本地时间为:2025-05-20 07:00:00
1.3 UTC 与本地时间的转换
- 转换公式:
- 本地时间 = UTC 时间 + 时区偏移量(需考虑是否启用夏令时)
- UTC 时间 = 本地时间 – 时区偏移量(需考虑是否启用夏令时)
- 示例:
- 若北京时间(UTC+8,非夏令时)为 2025-05-20 10:00:00,则对应的 UTC 时间为:
- UTC 时间 = 10:00 – 8 = 02:00,即 2025-05-20 02:00:00
- 若 UTC 时间为 2025-05-20 12:00:00,则纽约时间(UTC-5,非夏令时)为:
- 本地时间 = 12:00 + (-5) = 07:00,即 2025-05-20 07:00:00
- 若北京时间(UTC+8,非夏令时)为 2025-05-20 10:00:00,则对应的 UTC 时间为:
1.4 时间戳
- 定义:时间戳(Timestamp)通常表示自 1970 年 1 月 1 日 00:00:00 UTC(称为 Unix 纪元)以来经过的秒数。
- 特点:
- 是 UTC 时间的一种数值化表示形式,不依赖于任何时区。
- 便于程序进行时间的比较、存储和计算。
2 time() 函数
2.1 函数原型
#include <time.h> // 必须包含此头文件才能使用 time() 函数
time_t time(time_t *timer);
2.2 功能说明
time() 函数用于获取当前的日历时间(即从 1970 年 1 月 1 日 00:00:00 UTC 开始经过的秒数,不包括闰秒),并将其作为 time_t 类型的值返回。
time_t 类型通常是一个长整型(如 long 或 long long),用于表示时间戳(秒数)。在 printf 中输出时,常用 %ld 或 %lld 作为占位符,具体取决于平台。最常用写法(搭配强制转换):printf("%ld", (long)now) 。
- 参数:
- timer:一个指向 time_t 类型变量的指针。
- 如果该参数不为 NULL,则当前时间也会被存储到该指针指向的变量中;
- 若为 NULL 或 0,则仅返回时间值。
- timer:一个指向 time_t 类型变量的指针。
- 返回值:
- 成功时返回当前的时间值(以秒为单位的 time_t 类型)。
- 如果失败(例如系统无法获取当前时间),返回 (time_t)(-1)。
2.3 注意事项
2.4 应用场景
2.5 示例程序
#include <stdio.h>
#include <time.h> // 必须包含此头文件才能使用 time() 函数
int main()
{
time_t current_time; // 声明一个 time_t 类型的变量来存储当前时间戳
// 情况 1:参数为 NULL,仅返回当前时间值
time_t returned_time = time(NULL);
// 可选的检查返回值
if (returned_time == (time_t)-1)
{
printf("无法获取当前时间(参数为 NULL 的情况)。\\n");
}
else
{
printf("情况1(参数为 NULL):当前时间戳:%ld\\n", (long)returned_time);
}
// 情况 2:参数为 0,仅返回当前时间值
printf("情况2(参数为 0):当前时间戳:%ld\\n", (long)time(0));
// 情况 3:参数为非 NULL,当前时间会被存储到指针指向的变量中
time(¤t_time); // 传入变量的地址,将当前时间戳存储到该变量中
// 一般不检查返回值,直接使用
printf("情况3(参数为非 NULL):当前时间戳:%ld\\n", (long)current_time);
return 0;
}
程序在 VS Code 中的运行结果如下所示:
3 ctime() 函数
3.1 函数原型
#include <time.h> // 必须包含此头文件才能使用 ctime() 函数
char *ctime(const time_t *timer);
3.2 功能说明
ctime() 函数用于将 time_t 类型表示的时间值(即时间戳)转换为一个可读性良好的字符串形式,返回的是一个表示本地时间的字符串。
- 参数:
- timer:指向一个 time_t 类型变量的指针,表示要转换的时间值。
- 返回值:
- 成功时返回一个指向静态字符数组的指针,该数组中保存了格式化后的时间字符串;
- 如果失败(如传入的 timer 为 NULL 或系统内部错误),则返回 NULL。
3.3 注意事项
3.4 应用场景
3.5 示例程序
#include <stdio.h>
#include <time.h> // 必须包含此头文件才能使用 time() 和 ctime() 函数
int main()
{
time_t current_time; // 声明一个 time_t 类型的变量来存储当前时间戳
// 情况 1:参数为 NULL,仅返回当前时间值
time_t returned_time = time(NULL);
// 可选的检查返回值
if (returned_time == (time_t)-1)
{
printf("无法获取当前时间(参数为 NULL 的情况)。\\n");
}
else
{
printf("情况1(参数为 NULL):当前时间戳:%ld\\n", (long)returned_time);
// 使用 ctime 输出可读时间字符串
printf("情况1 对应的本地时间:%s", ctime(&returned_time)); // 不需要换行符,ctime() 函数会自动添加
}
// 情况 2:参数为非 NULL,当前时间会被存储到指针指向的变量中
time(¤t_time); // 传入变量的地址,将当前时间戳存储到该变量中
printf("情况2(参数为非 NULL):当前时间戳:%ld\\n", (long)current_time);
// 使用 ctime 输出可读时间字符串
printf("情况2 对应的本地时间:%s", ctime(¤t_time)); // 不需要换行符,ctime() 函数会自动添加
return 0;
}
程序在 VS Code 中的运行结果如下所示:
4 difftime() 函数
4.1 函数原型
#include <time.h> // 必须包含此头文件才能使用 difftime() 函数
double difftime(time_t time2, time_t time1);
4.2 功能说明
difftime() 函数用于计算两个时间点之间的时间差(以秒为单位)。这两个时间点通常是由 time() 函数获取的 time_t 类型的时间戳。
- 参数:
- time2:结束时间,一个 time_t 类型值。
- time1:开始时间,一个 time_t 类型值。
- 返回值:
- 返回 time2 – time1 的差值,结果以 double 类型表示,单位为秒;
- 如果 time2 比 time1 小(即结束时间早于开始时间),则返回负数。
4.3 注意事项
4.4 应用场景
4.5 示例程序
#include <stdio.h>
#include <time.h> // 必须包含此头文件才能使用 time() 和 difftime() 函数
int main()
{
time_t start_time, end_time; // 定义两个 time_t 变量用于保存时间戳
printf("程序开始计时…\\n");
start_time = time(NULL); // 获取开始时间
// 模拟耗时操作(通过循环延时)
for (unsigned long long i = 0; i < 10000000000LL; ++i)
; // 简单延迟
end_time = time(NULL); // 获取结束时间
// 使用 difftime 计算时间差
double elapsed_seconds = difftime(end_time, start_time);
printf("程序结束计时。\\n");
printf("经过的时间:%lf 秒\\n", elapsed_seconds);
return 0;
}
程序在 VS Code 中的运行结果如下所示:
5 clock() 函数
5.1 函数原型
#include <time.h> // 必须包含此头文件才能使用 clock() 函数
clock_t clock(void);
5.2 功能说明
clock() 函数返回自程序启动以来(或程序进入当前状态以来)的处理器时间(CPU 时间),单位通常是 “时钟滴答”(clock ticks)。该时间以 clock_t 类型表示,通常用于测量一段代码的 CPU 执行时间。
- 返回值:
- 返回当前进程使用的处理器时间(CPU 时间),单位为 CLOCKS_PER_SEC(每秒的时钟滴答数),而不是秒数;
- 示例:如果 CLOCKS_PER_SEC 是 1000000,则 clock() 返回的值除以 1000000 可以得到秒数。
- 因此,clock() 返回的滴答数除以 CLOCKS_PER_SEC 可以得到以秒为单位的 CPU 时间。
- 返回 (clock_t)(-1)(通常是 -1),并可能设置 errno(但标准未明确要求设置 errno,具体行为依赖实现)。
- 返回当前进程使用的处理器时间(CPU 时间),单位为 CLOCKS_PER_SEC(每秒的时钟滴答数),而不是秒数;
5.3 注意事项
5.4 应用场景
5.5 示例程序
#include <stdio.h>
#include <time.h> // 必须包含此头文件才能使用 clock() 函数
int main()
{
// 记录开始时间
clock_t start_time = clock();
// 模拟一个耗时的操作
for (unsigned long long i = 0; i < 10000000000LL; ++i)
; // 简单延迟
// 记录结束时间
clock_t end_time = clock();
// 计算消耗的 CPU 时间,并将其转换为秒(除以 CLOCKS_PER_SEC)
double cpu_time_used = ((double)(end_time – start_time)) / CLOCKS_PER_SEC;
printf("模拟操作消耗的 CPU 时间: %lf 秒\\n", cpu_time_used);
return 0;
}
程序在 VS Code 中的运行结果如下所示:
6 日期与时间函数总结
time | 获取当前时间戳(自 1970-01-01 00:00:00 UTC 起经过的秒数) | time_t *timer:可为 NULL,用于接收时间戳 | 成功返回时间戳(time_t 类型),失败返回 (time_t)-1 |
ctime | 将时间戳转换为可读的本地时间字符串(格式固定,带换行符) | const time_t *timer:指向时间戳的指针 | 成功返回指向静态字符串的指针,失败返回 NULL |
difftime | 计算两个时间点之间的时间差(以秒为单位) | time_t time2, time_t time1:两个时间点 | 返回 time2 – time1 的差值(double 类型,单位为秒) |
clock | 获取当前进程使用的 CPU 时间(从程序启动开始计算) | 无参数 | 成功返回 CPU 使用时间(以时钟周期为单位),失败返回 (clock_t)-1 |
补充说明:
- time_t 类型:通常为长整型(如 long 或 long long),用于表示自 Unix 纪元(1970-01-01 00:00:00 UTC)以来经过的秒数,即时间戳。
- ctime() 的线程安全性:该函数返回一个指向内部静态缓冲区的指针,内容在每次调用时会被覆盖。
- difftime() 的优势:该函数基于标准 C 定义,能够准确计算两个时间点之间的差值,单位为秒(支持小数),适用于跨平台、跨时区的时间差比较,是推荐的标准方法。
- clock() 的局限性:它返回的是程序所占用的 CPU 时间,而非真实世界时间(wall-clock time),因此不适合用于测量 I/O 操作、睡眠或等待外部事件的时间。
评论前必须登录!
注册