C++获取时间和格式化时间

714 阅读4分钟

一、获取当前时间

1、 跨平台

1.1、std::chrono::system_clock::now
函数声明
std::chrono::system_clock::time_point std::chrono::system_clock::now();
示例代码
#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()

函数声明
time_t time(time_t *t);
示例代码
#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

函数声明
GetSystemTimeAsFileTime(_Out_ LPFILETIME lpSystemTimeAsFileTime);
示例代码
#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

函数声明
BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount);
示例代码
#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

函数声明
int clock_gettime(clockid_t clk_id, struct timespec *tp);
示例代码
#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

函数声明
int gettimeofday(struct timeval *tv, struct timezone *tz);
示例代码
#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()跨平台基础时间戳获取精度低,非线程安全
GetSystemTimeAsFileTime100纳秒WindowsWindows高精度时间获取需转换为通用格式
QueryPerformanceCounter纳秒Windows高精度性能计时单调递增计数器,不是当前时间
clock_gettime纳秒POSIX(Linux/macOS)高精度系统时间和计时支持多种时钟类型
gettimeofday微秒POSIX(Linux/macOS)旧系统兼容已被 clock_gettime 替代

二、格式化时间

1 跨平台(标准 C 库)

1.1 ctime
  • 函数声明
char* ctime(const time_t* timer);
  • 说明:将 time_t(时间戳)转换为可读字符串,线程不安全
  • 平台支持:✅ Windows、Linux、Unix 通用。
  • 示例
#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):
errno_t localtime_s(struct tm* _Tm, const time_t* _Time);
  • 说明:安全版本的 localtime,线程安全。
  • 头文件<time.h><ctime>
  • 示例
#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):
struct tm* localtime_r(const time_t* timep, struct tm* result);
  • 说明:线程安全版本的 localtime,适用于 Linux、Unix、macOS。
  • 头文件<time.h><ctime>
  • 示例
#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
  • 通常是 longlong long 类型,表示自 1970-01-01 00:00:00 UTC 起的秒数。
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 表示 1 月)
    int tm_year;  // 年(从 1900 年开始)
    int tm_wday;  // 星期 [0, 6](0 表示星期天)
    int tm_yday;  // 年内天数 [0, 365]
    int tm_isdst; // 夏令时标志
};

总结对比表

函数名平台线程安全说明
ctime跨平台时间戳 → 字符串
ctime_sWindows安全版 ctime
ctime_rUnix/POSIX安全版 ctime
localtime跨平台时间戳 → tm 结构体
localtime_sWindows安全版 localtime
localtime_rUnix/POSIX安全版 localtime