什么是时间戳?
时间戳是一个表示特定时间点的数值,它本质上是一个从某个固定时间点(称为“纪元”或“Epoch”)开始所经过的秒数(或毫秒数等)。

(图片来源网络,侵删)
最常见的时间戳是 Unix 时间戳,它从 1970年1月1日 00:00:00 UTC(协调世界时) 开始计算,这是一个全球统一的标准,便于在不同系统和编程语言之间交换时间信息。
在 C 语言中,主要有两种方式来处理时间戳和时间:
<time.h>库(C 标准库):最传统、最通用的方法,处理秒级时间戳。<chrono.h>库(C++11 及更高版本):虽然不是 C 语言,但现代 C++ 项目中非常流行,提供更强大和易用的功能。
我们重点讲解 C 标准库中的 <time.h>。
使用 <time.h> 库处理时间戳
<time.h> 是 C 语言处理日期和时间的核心头文件,它提供了几个关键的类型和函数。

(图片来源网络,侵删)
核心数据类型
time_t: 用于表示时间的算术类型,通常被定义为long或long long整数,它存储的就是 Unix 时间戳(秒数)。struct tm: 一个结构体,用于将时间戳分解为年、月、日、时、分、秒等更易读的格式。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; // 夏令时标志,正数表示夏令时,0表示非夏令时,负数表示未知 };
核心函数
获取当前时间戳
time_t time(time_t *tptr);
- 功能:获取当前的日历时间。
- 参数:
- 如果传入一个非空的
time_t*指针,函数会将当前时间戳同时存储在该指针指向的内存位置和返回值中。 - 如果传入
NULL,函数只通过返回值返回当前时间戳。
- 如果传入一个非空的
- 返回值:成功则返回当前时间戳(
time_t类型),失败则返回(time_t)-1。
示例代码:
#include <stdio.h>
#include <time.h> // 必须包含的头文件
int main() {
// 1. 获取当前时间戳
time_t raw_time;
time(&raw_time); // 将当前时间戳存储在 raw_time 变量中
printf("当前时间戳 (秒): %ld\n", raw_time);
// 也可以这样写
time_t another_time = time(NULL);
printf("另一个方式获取的时间戳: %ld\n", another_time);
return 0;
}
将时间戳转换为可读的本地时间
struct tm *localtime(const time_t *tptr);
- 功能:将
time_t格式的时间戳转换为struct tm结构体,表示的是本地时区的时间。 - 参数:指向
time_t时间戳的指针。 - 返回值:指向
struct tm结构体的指针。注意:这个返回的指针指向的是一个静态分配的内存区域,每次调用localtime都会覆盖上一次的结果,如果你需要长时间保存转换后的时间,应该手动复制struct tm结构体的内容。
示例代码:

(图片来源网络,侵删)
#include <stdio.h>
#include <time.h>
int main() {
time_t raw_time;
time(&raw_time);
// 2. 将时间戳转换为本地时间的结构体
struct tm *time_info = localtime(&raw_time);
// 3. 使用 printf 的格式化输出来打印时间
// %02d 表示输出两位整数,不足的前面补0
printf("本地时间: %d-%02d-%02d %02d:%02d:%02d\n",
time_info->tm_year + 1900, // tm_year 从1900开始,所以要加1900
time_info->tm_mon + 1, // tm_mon 从0开始,所以要加1
time_info->tm_mday,
time_info->tm_hour,
time_info->tm_min,
time_info->tm_sec);
return 0;
}
将时间戳转换为可读的UTC时间
struct tm *gmtime(const time_t *tptr);
- 功能:与
localtime类似,但转换后的时间是UTC(格林威治标准时间),不受本地时区影响。 - 使用方法和注意事项与
localtime完全相同。
示例代码:
#include <stdio.h>
#include <time.h>
int main() {
time_t raw_time;
time(&raw_time);
struct tm *utc_time_info = gmtime(&raw_time);
printf("UTC时间: %d-%02d-%02d %02d:%02d:%02d\n",
utc_time_info->tm_year + 1900,
utc_time_info->tm_mon + 1,
utc_time_info->tm_mday,
utc_time_info->tm_hour,
utc_time_info->tm_min,
utc_time_info->tm_sec);
return 0;
}
将 struct tm 结构体转换回时间戳
time_t mktime(struct tm *tptr);
- 功能:将
struct tm结构体(表示本地时间)转换回time_t时间戳。 - 参数:指向
struct tm结构体的指针。 - 返回值:成功则转换后的时间戳,失败则返回
(time_t)-1,这个函数会自动处理struct tm中超出范围的值(tm_min=70会被自动进位)。
示例代码:
#include <stdio.h>
#include <time.h>
int main() {
// 创建一个表示 2025年10月27日 15:30:00 的时间结构体
struct tm my_time = {0};
my_time.tm_year = 2025 - 1900; // 123
my_time.tm_mon = 10 - 1; // 9
my_time.tm_mday = 27;
my_time.tm_hour = 15;
my_time.tm_min = 30;
my_time.tm_sec = 0;
my_time.tm_isdst = -1; // 让系统自动判断夏令时
// 将结构体转换回时间戳
time_t converted_timestamp = mktime(&my_time);
if (converted_timestamp == -1) {
perror("mktime 转换失败");
return 1;
}
printf("自定义时间对应的时间戳: %ld\n", converted_timestamp);
// 验证一下:将时间戳再转回来
struct tm *verified_time_info = localtime(&converted_timestamp);
printf("验证后的时间: %d-%02d-%02d %02d:%02d:%02d\n",
verified_time_info->tm_year + 1900,
verified_time_info->tm_mon + 1,
verified_time_info->tm_mday,
verified_time_info->tm_hour,
verified_time_info->tm_min,
verified_time_info->tm_sec);
return 0;
}
获取更高精度的时间(毫秒/微秒)
标准 C 库的 time() 函数精度只有秒级,如果需要毫秒或微秒级别的精度,可以使用平台相关的函数。
- 在 Linux/Unix 系统上:
<sys/time.h>中的gettimeofday()函数(已在新标准中弃用,但仍广泛使用)。<time.h>中的clock_gettime()函数(推荐,更现代、精度更高)。
clock_gettime() 示例:
#include <stdio.h>
#include <time.h> // 包含 clock_gettime
int main() {
struct timespec ts;
// 获取当前时间,使用 CLOCK_REALTIME (类似 wall-clock time)
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
perror("clock_gettime");
return 1;
}
// ts.tv_sec 是秒数部分
// ts.tv_nsec 是纳秒 (10^-9秒) 部分
time_t raw_time = ts.tv_sec;
long milliseconds = ts.tv_nsec / 1000000; // 纳秒转毫秒
struct tm *time_info = localtime(&raw_time);
printf("高精度时间: %d-%02d-%02d %02d:%02d:%02d.%03ld\n",
time_info->tm_year + 1900,
time_info->tm_mon + 1,
time_info->tm_mday,
time_info->tm_hour,
time_info->tm_min,
time_info->tm_sec,
milliseconds);
return 0;
}
将时间戳转换为字符串
除了 printf 的格式化输出,<time.h> 还提供了专门的函数。
char *ctime(const time_t *tptr);
- 功能:将
time_t时间戳直接转换为一个易读的字符串格式("Fri Oct 27 15:30:00 2025\n")。 - 注意:和
localtime一样,它返回的也是指向静态内存的指针,不能被长期保存。
size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *tptr);
- 功能:这是一个更强大、更灵活的函数,允许你自定义输出字符串的格式。
- 参数:
str: 存储结果的字符数组。maxsize:str数组的大小。format: 格式化字符串,类似于printf。tptr: 指向struct tm结构体的指针。
- 返回值:成功则写入的字符数(不包括结尾的
\0),失败则返回 0。
strftime 格式化字符示例:
| 格式字符 | 含义 | 示例 |
|---|---|---|
%Y |
4位数年份 | 2025 |
%m |
2位数月份 (01-12) | 10 |
%d |
2位数日期 (01-31) | 27 |
%H |
24小时制小时 (00-23) | 15 |
%M |
分钟 (00-59) | 30 |
%S |
秒 (00-59) | 05 |
%F |
等同于 %Y-%m-%d |
2025-10-27 |
%T |
等同于 %H:%M:%S |
15:30:05 |
%s |
Unix 时间戳 (非标准,但常见) | 1698388205 |
strftime 示例代码:
#include <stdio.h>
#include <time.h>
int main() {
time_t raw_time;
time(&raw_time);
struct tm *time_info = localtime(&raw_time);
char buffer[80];
// 使用 strftime 格式化时间
strftime(buffer, sizeof(buffer), "现在是 %Y年%m月%d日 %H:%M:%S", time_info);
printf("%s\n", buffer);
// 另一个格式
strftime(buffer, sizeof(buffer), "%F %T", time_info);
printf("%s\n", buffer);
return 0;
}
总结与最佳实践
| 任务 | 推荐函数 | 说明 |
|---|---|---|
| 获取当前秒级时间戳 | time(NULL) |
简单直接,C标准库。 |
| 将时间戳转本地时间 | localtime(×tamp) |
注意返回的是静态指针。 |
| 将时间戳转UTC时间 | gmtime(×tamp) |
不受时区影响。 |
| 将时间结构体转时间戳 | mktime(&time_struct) |
自动处理进位,是 localtime 的逆操作。 |
| 获取毫秒/微秒级时间戳 | clock_gettime(CLOCK_REALTIME, &ts) |
Linux/Unix推荐,精度高。 |
| 快速格式化时间戳为字符串 | ctime(×tamp) |
简单,但格式固定。 |
| 自定义格式化时间 | strftime(buffer, size, format, &time_struct) |
最推荐,灵活强大。 |
一个完整的示例:获取、转换、格式化
#include <stdio.h>
#include <time.h>
int main() {
// 1. 获取当前时间戳
time_t now_timestamp = time(NULL);
if (now_timestamp == -1) {
perror("获取时间失败");
return 1;
}
printf("原始时间戳: %ld\n", now_timestamp);
// 2. 转换为本地时间结构体
struct tm *now_tm = localtime(&now_timestamp);
if (now_tm == NULL) {
perror("本地时间转换失败");
return 1;
}
// 3. 使用 strftime 进行自定义格式化
char time_string[100];
strftime(time_string, sizeof(time_string), "%Y-%m-%d %H:%M:%S %A", now_tm);
printf("格式化后的本地时间: %s\n", time_string);
// 4. 转换为UTC时间并格式化
struct tm *utc_tm = gmtime(&now_timestamp);
if (utc_tm == NULL) {
perror("UTC时间转换失败");
return 1;
}
char utc_string[100];
strftime(utc_string, sizeof(utc_string), "%Y-%m-%d %H:%M:%S (UTC)", utc_tm);
printf("格式化后的UTC时间: %s\n", utc_string);
return 0;
}
希望这份详细的讲解能帮助你完全掌握 C 语言中的时间戳处理!
