timestamp在C语言中如何使用?

99ANYc3cd6
预计阅读时长 30 分钟
位置: 首页 C语言 正文

什么是时间戳?

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

timestamp c语言
(图片来源网络,侵删)

最常见的时间戳是 Unix 时间戳,它从 1970年1月1日 00:00:00 UTC(协调世界时) 开始计算,这是一个全球统一的标准,便于在不同系统和编程语言之间交换时间信息。

在 C 语言中,主要有两种方式来处理时间戳和时间:

  1. <time.h> 库(C 标准库):最传统、最通用的方法,处理秒级时间戳。
  2. <chrono.h> 库(C++11 及更高版本):虽然不是 C 语言,但现代 C++ 项目中非常流行,提供更强大和易用的功能。

我们重点讲解 C 标准库中的 <time.h>


使用 <time.h> 库处理时间戳

<time.h> 是 C 语言处理日期和时间的核心头文件,它提供了几个关键的类型和函数。

timestamp c语言
(图片来源网络,侵删)

核心数据类型

  • time_t: 用于表示时间的算术类型,通常被定义为 longlong 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 结构体的内容。

示例代码:

timestamp c语言
(图片来源网络,侵删)
#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(&timestamp) 注意返回的是静态指针。
将时间戳转UTC时间 gmtime(&timestamp) 不受时区影响。
将时间结构体转时间戳 mktime(&time_struct) 自动处理进位,是 localtime 的逆操作。
获取毫秒/微秒级时间戳 clock_gettime(CLOCK_REALTIME, &ts) Linux/Unix推荐,精度高。
快速格式化时间戳为字符串 ctime(&timestamp) 简单,但格式固定。
自定义格式化时间 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 语言中的时间戳处理!

-- 展开阅读全文 --
头像
dede如何修改联系方式?
« 上一篇 今天
C语言可重入函数如何实现与注意事项?
下一篇 » 今天

相关文章

取消
微信二维码
支付宝二维码

目录[+]