You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用std::chrono从毫秒级Epoch时间提取时间单位并操作日期?

解决C++中Epoch毫秒时间的日期提取与操作问题

需要注意:以下方案基于C++20及以上版本实现,标准库从C20开始正式引入chrono日历与时区组件。若使用旧版本C,需依赖Howard Hinnant的date第三方库(此处仅讲解标准库原生方案)。


1. 提取年、月、日、时、分、秒、毫秒

要从system_clock::time_point中提取时间单位,需先将其转换为结构化的日历类型(如year_month_day)和时分秒毫秒类型(如hh_mm_ss<milliseconds>)。以下是完整的getTimeUnit函数实现:

#include <chrono>
#include <iostream>

enum class DatePrecision { YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLI };

using namespace std::chrono;

int getTimeUnit(const system_clock::time_point& tp, const DatePrecision dp) {
    // 将时间点向下取整到UTC当天起始时刻,得到天数级的时间戳
    const auto utc_days = floor<days>(tp);
    // 转换为年-月-日结构化类型
    const year_month_day ymd{utc_days};
    
    // 计算当天已流逝的毫秒数,并解析为时-分-秒-毫秒
    const auto ms_since_midnight = floor<milliseconds>(tp - utc_days);
    const hh_mm_ss hms{ms_since_midnight};

    switch (dp) {
        case DatePrecision::YEAR:
            return static_cast<int>(ymd.year());
        case DatePrecision::MONTH:
            return static_cast<unsigned>(ymd.month());
        case DatePrecision::DAY:
            return static_cast<unsigned>(ymd.day());
        case DatePrecision::HOUR:
            return hms.hours().count();
        case DatePrecision::MINUTE:
            return hms.minutes().count();
        case DatePrecision::SECOND:
            return hms.seconds().count();
        case DatePrecision::MILLI:
            return hms.subseconds().count();
        default:
            return -1;
    }
}

int main() {
    long long et = 1693322440062;
    milliseconds ms{et};
    system_clock::time_point tp(ms);

    std::cout << "Year: " << getTimeUnit(tp, DatePrecision::YEAR) << "\n";
    std::cout << "Month: " << getTimeUnit(tp, DatePrecision::MONTH) << "\n";
    std::cout << "Day: " << getTimeUnit(tp, DatePrecision::DAY) << "\n";
    std::cout << "Hour: " << getTimeUnit(tp, DatePrecision::HOUR) << "\n";
    std::cout << "Minute: " << getTimeUnit(tp, DatePrecision::MINUTE) << "\n";
    std::cout << "Second: " << getTimeUnit(tp, DatePrecision::SECOND) << "\n";
    std::cout << "Milli: " << getTimeUnit(tp, DatePrecision::MILLI) << "\n";
    return 0;
}

代码说明

  • floor<days>(tp):将时间点向下取整到UTC当天的午夜时刻,得到代表Epoch以来天数的sys_days类型。
  • year_month_day{utc_days}:将天数转换为可读的年、月、日结构化数据。
  • tp - utc_days:计算当天已流逝的时长,转换为毫秒后用hh_mm_ss解析为时、分、秒、毫秒。
  • 上述代码默认处理UTC时间,若需要本地时间,需结合时区转换(见下文)。

2. 日期比较

chrono库已为time_point重载了所有比较运算符,直接使用即可:

system_clock::time_point tp1 = milliseconds{1693322440062};
system_clock::time_point tp2 = milliseconds{1693408840000};

if (tp1 < tp2) {
    std::cout << "tp1 早于 tp2\n";
}

若需比较年、月、日等日历单元,可先转换为year_month_day再比较:

year_month_day ymd1 = floor<days>(tp1);
year_month_day ymd2 = floor<days>(tp2);

if (ymd1 == ymd2) {
    std::cout << "两个时间点属于同一天\n";
}

3. 添加/减去小时、天数、月份

加减固定时长(小时、天数)

直接对time_point加减chrono::duration类型即可:

// 添加2小时
auto tp_plus_2h = tp + hours{2};
// 减去3天
auto tp_minus_3d = tp - days{3};

加减月份(日历级操作)

由于不同月份天数不同,需先转换为year_month_day,结合months类型操作后再转回time_point:

year_month_day ymd = floor<days>(tp);
// 添加1个月
auto ymd_plus_1m = ymd + months{1};
// 转换回system_clock的时间点
auto tp_plus_1m = system_clock::from_sys(sys_days{ymd_plus_1m});

4. 处理本地时间(替代UTC)

若需要将UTC时间转换为系统本地时间,需使用时区组件:

#include <chrono>
#include <iostream>

int main() {
    long long et = 1693322440062;
    milliseconds ms{et};
    system_clock::time_point tp_utc(ms);

    // 获取当前系统的本地时区
    const auto& local_tz = std::chrono::current_zone();
    // 将UTC时间转换为本地时间
    auto tp_local = local_tz->to_local(tp_utc);

    // 提取本地日期和时间
    auto local_days = floor<days>(tp_local);
    year_month_day ymd_local{local_days};
    auto ms_local = floor<milliseconds>(tp_local - local_days);
    hh_mm_ss hms_local{ms_local};

    std::cout << "本地年份: " << static_cast<int>(ymd_local.year()) << "\n";
    std::cout << "本地小时: " << hms_local.hours().count() << "\n";
    return 0;
}

常见问题解决

  • 无法运行cppreference示例:确保编译器启用C++20标准(GCC:-std=c++20,MSVC:/std:c++20,Clang:-std=c++20)。
  • utc_time与system_time的区别:system_clock::time_point本质就是UTC时间(sys_time),utc_time是更明确的UTC时间类型,两者可互相转换:utc_time<milliseconds> utc_tp{tp.time_since_epoch()};

内容的提问来源于stack exchange,提问作者Markstar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 04:54:55