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

C++中ISO 8601格式时间戳字符串的严格校验问题

校验ISO 8601时间戳合法性的解决方案

由于Boost和标准库chrono组件会自动调整非法时间值而非抛出错误,要实现严格校验需分两步:格式结构校验和数值合法性校验,以下是基于C++标准库的实现方案:

步骤1:格式匹配(正则表达式)

先用正则表达式匹配ISO 8601的核心格式(覆盖基本格式和扩展格式),确保时间戳的结构符合标准,避免混合分隔符等非法情况。

示例正则表达式:

const std::regex iso8601_regex(
    R"(^(\d{4})(-?)(\d{2})\2(\d{2})T(\d{2})(:?)(\d{2})\6(\d{2})(\.\d+)?$)"
);

该正则会强制分隔符(-和:)要么全有要么全无,同时匹配可选的小数秒部分。

步骤2:提取字段并做数值校验

格式匹配通过后,提取年、月、日、时、分、秒等字段,逐一校验数值范围:

核心校验规则

  • 月份:必须在1-12之间
  • 日期:根据月份和闰年判断合法天数(如2月平年28天、闰年29天;4/6/9/11月30天,其余月份31天)
  • 小时:0-23
  • 分钟:0-59
  • 秒:0-59(若需支持闰秒可放宽至0-60)
  • 年份:可根据业务需求添加范围限制(如1970-2100)

完整代码示例

#include <iostream>
#include <string>
#include <regex>
#include <stdexcept>

// 判断闰年
bool is_leap_year(int year) {
    if (year % 4 != 0) return false;
    if (year % 100 != 0) return true;
    return year % 400 == 0;
}

// 获取对应月份的最大天数
int get_max_day(int year, int month) {
    switch (month) {
        case 2: return is_leap_year(year) ? 29 : 28;
        case 4: case 6: case 9: case 11: return 30;
        default: return 31;
    }
}

// 校验ISO 8601时间戳合法性
bool validate_iso8601(const std::string& timestamp) {
    std::smatch match;
    const std::regex iso8601_regex(
        R"(^(\d{4})(-?)(\d{2})\2(\d{2})T(\d{2})(:?)(\d{2})\6(\d{2})(\.\d+)?$)"
    );

    // 格式匹配校验
    if (!std::regex_match(timestamp, match, iso8601_regex)) {
        return false;
    }

    // 提取字段并转为整数
    int year = std::stoi(match[1]);
    int month = std::stoi(match[3]);
    int day = std::stoi(match[4]);
    int hour = std::stoi(match[5]);
    int minute = std::stoi(match[7]);
    int second = std::stoi(match[8]);

    // 数值合法性校验
    if (month < 1 || month > 12) return false;
    if (day < 1 || day > get_max_day(year, month)) return false;
    if (hour < 0 || hour > 23) return false;
    if (minute < 0 || minute > 59) return false;
    if (second < 0 || second > 59) return false; // 支持闰秒可改为second <= 60

    return true;
}

int main() {
    // 测试用例
    std::string valid1 = "20021012T235920218"; // 合法基本格式
    std::string valid2 = "2002-10-12T23:59:20.218"; // 合法扩展格式
    std::string invalid_hour = "20021012T255920218"; // 小时溢出
    std::string invalid_date = "2014-02-30T21:35:34"; // 2月30日

    std::cout << valid1 << ": " << (validate_iso8601(valid1) ? "合法" : "非法") << std::endl;
    std::cout << valid2 << ": " << (validate_iso8601(valid2) ? "合法" : "非法") << std::endl;
    std::cout << invalid_hour << ": " << (validate_iso8601(invalid_hour) ? "合法" : "非法") << std::endl;
    std::cout << invalid_date << ": " << (validate_iso8601(invalid_date) ? "合法" : "非法") << std::endl;

    return 0;
}

代码说明

  1. 正则表达式确保时间戳结构严格符合ISO 8601规范,拒绝混合分隔符等非法格式;
  2. 数值校验通过手动判断月份天数、闰年等规则,直接拒绝所有溢出的时间值;
  3. 若业务需支持更多ISO 8601变体(如带时区、仅日期/时间部分),可扩展正则和校验逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 07:05:37