Linux C中获取含毫秒的墙钟时间是否仍繁琐?是否有便捷结构体?
在Linux C中获取带毫秒的墙钟时间:现状与实现方案
在Linux C环境下,确实没有标准提供的、能直接一步返回包含年/月/日/时/分/秒/毫秒的结构体和对应函数。这是因为系统时间API的设计逻辑是分层处理:先获取高精度的时间戳(包含秒级以下的精度),再将秒级部分转换为分解的墙钟时间字段,最后自行计算毫秒部分——这种设计能兼顾灵活性和资源复用,避免为不同精度重复定义结构体。
不过你完全可以自己封装出想要的接口,下面是两种常用的实现方式:
方式1:使用clock_gettime(推荐,POSIX标准)
clock_gettime是当前推荐的高精度时间获取接口,支持纳秒级精度,结合localtime_r(线程安全的时间分解函数)可以轻松实现需求:
#include <time.h> #include <stdio.h> // 定义你想要的时间结构体 typedef struct { int year; int month; int day; int hour; int minute; int second; int millisecond; } TIME_WITH_ALL_FIELDS; // 封装获取当前时间的函数 void get_now(TIME_WITH_ALL_FIELDS *now) { struct timespec ts; // 获取系统墙钟时间(包含纳秒) clock_gettime(CLOCK_REALTIME, &ts); struct tm tm_time; // 将秒级时间转换为分解的时间字段(线程安全) localtime_r(&ts.tv_sec, &tm_time); // 填充结构体字段 now->year = tm_time.tm_year + 1900; // tm_year是从1900开始的偏移量 now->month = tm_time.tm_mon + 1; // tm_mon范围是0-11,加1转为1-12 now->day = tm_time.tm_mday; now->hour = tm_time.tm_hour; now->minute = tm_time.tm_min; now->second = tm_time.tm_sec; // 将纳秒转换为毫秒(取前三位) now->millisecond = ts.tv_nsec / 1000000; } // 测试示例 int main() { TIME_WITH_ALL_FIELDS now; get_now(&now); printf("today is %04d-%02d-%02d %02d:%02d:%02d.%03d\n", now.year, now.month, now.day, now.hour, now.minute, now.second, now.millisecond); return 0; }
方式2:使用gettimeofday(兼容旧系统,已标记为过时)
如果需要兼容一些未完全支持clock_gettime的旧系统,可以用gettimeofday(它返回微秒级精度):
#include <sys/time.h> #include <time.h> #include <stdio.h> typedef struct { int year; int month; int day; int hour; int minute; int second; int millisecond; } TIME_WITH_ALL_FIELDS; void get_now(TIME_WITH_ALL_FIELDS *now) { struct timeval tv; gettimeofday(&tv, NULL); struct tm tm_time; localtime_r(&tv.tv_sec, &tm_time); now->year = tm_time.tm_year + 1900; now->month = tm_time.tm_mon + 1; now->day = tm_time.tm_mday; now->hour = tm_time.tm_hour; now->minute = tm_time.tm_min; now->second = tm_time.tm_sec; // 将微秒转换为毫秒 now->millisecond = tv.tv_usec / 1000; } // 测试示例同上
为什么没有原生接口?
POSIX和C标准库的时间API设计,是将时间戳获取和时间字段分解拆分为独立步骤:
- 时间戳获取函数(
clock_gettime/gettimeofday)负责提供高精度的原始时间数据; - 时间分解函数(
localtime_r/gmtime_r)负责将秒级时间转换为人类可读的年/月/日等字段。
这种设计的好处是:
- 避免重复定义结构体,不同精度的时间戳可以复用同一套分解函数;
- 允许开发者根据需求选择不同的时间源(比如
CLOCK_MONOTONIC用于计算时间差,CLOCK_REALTIME用于墙钟时间)。
内容的提问来源于stack exchange,提问作者Droidum
相关产品推荐
相关产品推荐

