一、获取当前时间
1、 跨平台
1.1、std::chrono::system_clock::now
函数声明
c
std::chrono::system_clock::time_point std::chrono::system_clock::now();
示例代码
c
#include <iostream>
#include <chrono>
#include <ctime>
int main() {
auto now = std::chrono::system_clock::now();
std::time_t t = std::chrono::system_clock::to_time_t(now);
std::cout << "当前时间戳: " << t << std::endl;
return 0;
}
TIP
- C++11及以后标准支持,类型安全,支持纳秒级精度(取决于系统);
- 推荐现代 C++ 项目使用;
- 跨平台支持 Windows/Linux/macOS。
2、 time()
函数声明
arduino
time_t time(time_t *t);
示例代码
arduino
#include <stdio.h>
#include <time.h>
int main() {
time_t t = time(NULL);
printf("当前时间戳: %ld\n", t);
return 0;
}
TIP
- 标准 C 库,所有平台均支持;
- 精度秒,线程不安全,不推荐使用
- 适合简单时间戳获取,不适合高精度场景。
2. Windows
1、GetSystemTimeAsFileTime
函数声明
scss
GetSystemTimeAsFileTime(_Out_ LPFILETIME lpSystemTimeAsFileTime);
示例代码
arduino
#include <windows.h>
#include <stdio.h>
int main() {
FILETIME ft; // FILETIME 结构体用于表示文件时间
GetSystemTimeAsFileTime(&ft);
// FILETIME 是100纳秒单位,从1601年1月1日起计数
ULARGE_INTEGER uli; // 使用 ULARGE_INTEGER 来处理 64 位整数
uli.LowPart = ft.dwLowDateTime;
uli.HighPart = ft.dwHighDateTime;
printf("当前时间(100纳秒单位):%llu\n", uli.QuadPart); // 打印当前时间的 100 纳秒单位表示
return 0;
}
TIP
- 需要将
FILETIME
转换为更易用格式; - 适合需要高精度系统时间的 Windows 应用。
2、 QueryPerformanceCounter
函数声明
scss
BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount);
示例代码
arduino
#include <windows.h>
#include <stdio.h>
int main() {
LARGE_INTEGER counter, freq;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&counter);
printf("性能计数器值: %lld,频率: %lld\n", counter.QuadPart, freq.QuadPart);
return 0;
}
TIP
- 高精度计时器,用于性能测量;
- 频率随硬件不同,一般在 MHz 级别;
- 非系统当前时间,而是单调递增计数器。
3. Linux
1、 clock_gettime
函数声明
arduino
int clock_gettime(clockid_t clk_id, struct timespec *tp);
示例代码
arduino
#include <stdio.h>
#include <time.h>
int main() {
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) == 0) {
printf("当前时间戳: %ld.%09ld 秒\n", ts.tv_sec, ts.tv_nsec);
} else {
perror("clock_gettime failed");
}
return 0;
}
TIP
- 支持多种时钟类型,如
CLOCK_REALTIME
,CLOCK_MONOTONIC
; - 精度纳秒,线程安全
2、 gettimeofday
函数声明
arduino
int gettimeofday(struct timeval *tv, struct timezone *tz);
示例代码
arduino
#include <stdio.h>
#include <sys/time.h>
int main() {
struct timeval tv;
gettimeofday(&tv, NULL);
printf("当前时间戳: %ld.%06ld 秒\n", tv.tv_sec, tv.tv_usec);
return 0;
}
TIP
- 精度微秒;
- 兼容性好,但是是老旧 API,POSIX 标准建议使用
clock_gettime
;
总结对比表
API 名称 | 精度 | 线程安全 | 平台支持 | 适用场景 | 备注 |
---|---|---|---|---|---|
std::chrono::system_clock |
纳秒 | ✅ | 跨平台(Win/Linux/macOS) | 现代 C++ 推荐 | 类型安全,易用 |
time() |
秒 | ❌ | 跨平台 | 基础时间戳获取 | 精度低,非线程安全 |
GetSystemTimeAsFileTime |
100纳秒 | ✅ | Windows | Windows高精度时间获取 | 需转换为通用格式 |
QueryPerformanceCounter |
纳秒 | ✅ | Windows | 高精度性能计时 | 单调递增计数器,不是当前时间 |
clock_gettime |
纳秒 | ✅ | POSIX(Linux/macOS) | 高精度系统时间和计时 | 支持多种时钟类型 |
gettimeofday |
微秒 | ✅ | POSIX(Linux/macOS) | 旧系统兼容 | 已被 clock_gettime 替代 |
二、格式化时间
1 跨平台(标准 C 库)
1.1 ctime
- 函数声明:
arduino
char* ctime(const time_t* timer);
- 说明 :将
time_t
(时间戳)转换为可读字符串,线程不安全。 - 平台支持:✅ Windows、Linux、Unix 通用。
- 示例:
arduino
#include <time.h>
#include <stdio.h>
int main() {
time_t timer;
time(&timer);
char* buf = ctime(&timer); // 非线程安全
printf("当前系统时间: %s\n", buf);
return 0;
}
2 Windows
2.1 localtime_s
- 原型(MSVC):
arduino
errno_t localtime_s(struct tm* _Tm, const time_t* _Time);
- 说明 :安全版本的
localtime
,线程安全。 - 头文件 :
<time.h>
或<ctime>
- 示例:
c
#include <stdio.h>
#include <time.h>
int main() {
time_t rawtime;
struct tm timeinfo;
char buf[26];
time(&rawtime);
if (localtime_s(&timeinfo, &rawtime) != 0) {
printf("时间转换失败\n");
return 1;
}
asctime_s(buf, sizeof(buf), &timeinfo);
printf("当前时间: %s", buf);
return 0;
}
2.2 _localtime32_s
/ _localtime64_s
-
区别:
_localtime32_s
:仅支持 1970~2038 年(32 位)_localtime64_s
:支持扩展到 3000+ 年(64 位)
-
仅限 MSVC 使用 ,调用类似于
localtime_s
。
3 Unix / Linux 专用
3.1 localtime_r
- 原型(POSIX):
c
struct tm* localtime_r(const time_t* timep, struct tm* result);
- 说明 :线程安全版本的
localtime
,适用于 Linux、Unix、macOS。 - 头文件 :
<time.h>
或<ctime>
- 示例:
c
#include <stdio.h>
#include <time.h>
int main() {
time_t now;
struct tm timeinfo;
char buf[26];
time(&now);
if (localtime_r(&now, &timeinfo) == NULL) {
printf("时间转换失败\n");
return 1;
}
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &timeinfo);
printf("当前时间: %s\n", buf);
return 0;
}
补充:时间相关结构说明
time_t
- 通常是
long
或long long
类型,表示自 1970-01-01 00:00:00 UTC 起的秒数。
struct tm
arduino
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 表示 1 月)
int tm_year; // 年(从 1900 年开始)
int tm_wday; // 星期 [0, 6](0 表示星期天)
int tm_yday; // 年内天数 [0, 365]
int tm_isdst; // 夏令时标志
};
总结对比表
函数名 | 平台 | 线程安全 | 说明 |
---|---|---|---|
ctime |
跨平台 | ❌ | 时间戳 → 字符串 |
ctime_s |
Windows | ✅ | 安全版 ctime |
ctime_r |
Unix/POSIX | ✅ | 安全版 ctime |
localtime |
跨平台 | ❌ | 时间戳 → tm 结构体 |
localtime_s |
Windows | ✅ | 安全版 localtime |
localtime_r |
Unix/POSIX | ✅ | 安全版 localtime |