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

C++如何解析HH:MM:SS.微秒格式时间戳字符串以便比较排序

解决方案

因为你的时间戳仅包含单日的时分秒和微秒,没有日期时区信息,直接用std::chrono::microseconds存储从当天0点开始的总微秒数即可,该类型原生支持比较、排序运算,完全满足需求,比std::chrono::time_point更轻量。

实现要点

  • 用C++17新增的std::from_chars做字符串到数值的转换,性能更高、无额外内存分配,也不存在locale兼容问题
  • 对输入格式和数值范围做校验,避免非法输入导致异常结果
  • 解析结果直接支持所有比较操作和标准库排序算法

完整可运行代码

#include <iostream>
#include <vector>
#include <string>
#include <chrono>
#include <algorithm>
#include <charconv>
#include <stdexcept>

// 输入格式要求:HH:MM:SS.ffffff,时分秒固定2位,微秒固定6位
std::chrono::microseconds parse_time(const std::string& ts_str) {
    // 若输入没有严格补前导零,可删除该长度校验,改用find查找冒号、小数点位置拆分字段
    if (ts_str.size() != 15) {
        throw std::invalid_argument("Invalid timestamp length");
    }

    int hh, mm, ss, us;
    // 解析小时
    auto res = std::from_chars(ts_str.data(), ts_str.data() + 2, hh);
    if (res.ec != std::errc() || res.ptr != ts_str.data() + 2 || ts_str[2] != ':') {
        throw std::invalid_argument("Invalid hour field");
    }
    // 解析分钟
    res = std::from_chars(ts_str.data() + 3, ts_str.data() + 5, mm);
    if (res.ec != std::errc() || res.ptr != ts_str.data() + 5 || ts_str[5] != ':') {
        throw std::invalid_argument("Invalid minute field");
    }
    // 解析秒
    res = std::from_chars(ts_str.data() + 6, ts_str.data() + 8, ss);
    if (res.ec != std::errc() || res.ptr != ts_str.data() + 8 || ts_str[8] != '.') {
        throw std::invalid_argument("Invalid second field");
    }
    // 解析微秒
    res = std::from_chars(ts_str.data() + 9, ts_str.data() + 15, us);
    if (res.ec != std::errc() || res.ptr != ts_str.data() + 15) {
        throw std::invalid_argument("Invalid microsecond field");
    }

    // 数值范围校验
    if (hh < 0 || hh > 23 || mm < 0 || mm > 59 || ss < 0 || ss > 59 || us < 0 || us > 999999) {
        throw std::invalid_argument("Timestamp value out of range");
    }

    using namespace std::chrono_literals;
    return hh * 3600000000us + mm * 60000000us + ss * 1000000us + std::chrono::microseconds(us);
}

int main() {
    std::vector<std::string> raw_ts = {
        "12:27:37.740002",
        "19:37:17.314002",
        "20:00:07.140902",
        "20:00:07.000000"
    };

    // 批量解析
    std::vector<std::chrono::microseconds> parsed_ts;
    parsed_ts.reserve(raw_ts.size());
    for (const auto& s : raw_ts) {
        parsed_ts.push_back(parse_time(s));
    }

    // 示例:时间比较
    auto t_a = parse_time("20:00:07.140902");
    auto t_b = parse_time("20:00:07.000000");
    if (t_a > t_b) {
        std::cout << "20:00:07.140902 晚于 20:00:07.000000" << std::endl;
    }

    // 示例:排序
    std::sort(parsed_ts.begin(), parsed_ts.end());

    return 0;
}

可选扩展

如果你确实需要使用std::chrono::time_point类型存储,只需要将解析得到的微秒数和当天0点的time_point相加即可,逻辑如下:

std::chrono::sys_time<std::chrono::microseconds> to_time_point(std::chrono::microseconds day_offset) {
    // 取当天0点的时间戳,根据你实际的日期需求调整即可
    auto today = std::chrono::floor<std::chrono::days>(std::chrono::system_clock::now());
    return today + day_offset;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 05:36:11