如何验证boost::datetime转换正确性?如何捕获非法输入并抛异常?
使用Boost.DateTime实现带合法性校验的字符串转时间对象
Boost.DateTime默认的字符串解析逻辑不会对非法输入抛出异常,而是生成错误的时间值,比如"2006-04-25 24:25:25"这类无效时间或完全不合法的字符串,都会导致隐性bug。以下是带完整合法性校验的实现方案:
核心实现代码
#include <boost/date_time/gregorian/gregorian.hpp> #include <boost/date_time/posix_time/posix_time.hpp> #include <stdexcept> #include <string> #include <sstream> namespace pt = boost::posix_time; namespace gr = boost::gregorian; pt::ptime string_to_ptime(const std::string& time_str, const std::string& format = "%Y-%m-%d %H:%M:%S") { // 初始化解析器 pt::time_input_facet* facet = new pt::time_input_facet(format); std::istringstream iss(time_str); iss.imbue(std::locale(iss.getloc(), facet)); pt::ptime parsed_time; iss >> parsed_time; // 检查解析是否完全成功:流无错误且所有字符都被读取 if (!iss.eof() || iss.fail()) { throw std::invalid_argument("Invalid time string format: " + time_str); } // 校验时间分量合法性:时/分/秒必须在有效范围内 pt::time_duration td = parsed_time.time_of_day(); if (td.hours() < 0 || td.hours() > 23 || td.minutes() < 0 || td.minutes() > 59 || td.seconds() < 0 || td.seconds() > 59) { throw std::invalid_argument("Invalid time components in string: " + time_str); } // 校验日期合法性:利用Boost内置的日期有效性检查 gr::date date_part = parsed_time.date(); if (!date_part.is_valid()) { throw std::invalid_argument("Invalid date components in string: " + time_str); } return parsed_time; }
关键校验逻辑说明
- 流状态校验:通过
iss.eof()确认输入字符串被完全解析,iss.fail()判断解析过程是否出错,能直接拦截完全不合法的字符串(如"incorrect_string")。 - 时间分量校验:手动检查时(0-23)、分(0-59)、秒(0-59)的范围,避免出现"24:00:00"这类无效时间。
- 日期合法性校验:借助Boost的
date::is_valid()方法,自动校验日期是否为合法公历日期(如2月30日、13月等都会被拦截)。 - 异常处理:所有非法场景统一抛出
std::invalid_argument异常,并携带具体错误信息,便于定位问题。
验证示例
#include <iostream> int main() { // 合法输入测试 try { auto valid_time = string_to_ptime("2006-04-25 23:25:25"); std::cout << "Parsed valid time: " << valid_time << std::endl; } catch (const std::exception& e) { std::cout << "Error: " << e.what() << std::endl; } // 无效小时(24点)测试 try { auto invalid_hour = string_to_ptime("2006-04-25 24:25:25"); std::cout << "Parsed valid time: " << invalid_hour << std::endl; } catch (const std::exception& e) { std::cout << "Error: " << e.what() << std::endl; } // 完全非法字符串测试 try { auto invalid_str = string_to_ptime("incorrect_string"); std::cout << "Parsed valid time: " << invalid_str << std::endl; } catch (const std::exception& e) { std::cout << "Error: " << e.what() << std::endl; } // 无效日期(2月30日)测试 try { auto invalid_date = string_to_ptime("2006-02-30 12:00:00"); std::cout << "Parsed valid time: " << invalid_date << std::endl; } catch (const std::exception& e) { std::cout << "Error: " << e.what() << std::endl; } return 0; }
运行输出
Parsed valid time: 2006-Apr-25 23:25:25 Error: Invalid time components in string: 2006-04-25 24:25:25 Error: Invalid time string format: incorrect_string Error: Invalid date components in string: 2006-02-30 12:00:00
内容的提问来源于stack exchange,提问作者lbsmart
相关产品推荐
相关产品推荐

