如何使用HowardHinnant/date库解析'PT6M2S'格式的时长?
如何用HowardHinnant/date库解析ISO 8601时长格式(如PT6M2S)
你遇到的问题主要是用错了格式说明符和不合适的接收类型——这个库完全支持解析ISO 8601的时长格式,只是需要用正确的姿势来实现。
先说说你当前代码的问题:%X是用来解析时间点格式(比如12:34:56)的,不是针对PT开头的时长格式;另外直接用minutes类型只能接收纯分钟的时长,遇到包含秒的格式(比如PT6M2S)就会解析失败。
下面是正确的实现方式,我会分步骤说明:
核心要点
HowardHinnant/date库专门提供了%P格式说明符,用来解析ISO 8601的周期格式(包括PnYnMnDTnHnMnS这种完整格式,以及PT6M2S这种纯时间时长)。你只需要用合适的std::chrono::duration类型来接收解析结果即可。
完整代码示例
#include "date.h" #include <iostream> #include <sstream> #include <chrono> int main() { using namespace date; using namespace std::chrono; // 解析包含分钟和秒的时长:PT6M2S std::istringstream in{"PT6M2S"}; seconds total_seconds; in >> parse("%P", total_seconds); if (in.fail()) { std::cout << "解析失败" << std::endl; } else { std::cout << "总时长:" << total_seconds.count() << "秒" << std::endl; // 可选:将总秒数分解为分钟和秒 auto mins = duration_cast<minutes>(total_seconds); auto secs = total_seconds - mins; std::cout << "分解结果:" << mins.count() << "分钟 " << secs.count() << "秒" << std::endl; } // 解析纯分钟的时长:PT6M std::istringstream in2{"PT6M"}; minutes only_mins; in2 >> parse("%P", only_mins); if (!in2.fail()) { std::cout << "\nPT6M解析结果:" << only_mins.count() << "分钟" << std::endl; } // 甚至可以解析包含小时、分钟、秒的混合格式,比如PT1H2M3S std::istringstream in3{"PT1H2M3S"}; hours total_hours; in3 >> parse("%P", total_hours); if (!in3.fail()) { std::cout << "\nPT1H2M3S解析为小时:" << total_hours.count() << "小时" << std::endl; } return 0; }
代码说明
- 格式说明符
%P:这是date库针对ISO 8601周期格式设计的专用解析符,能自动识别P开头的所有合法时长格式,包括带日期部分的(比如P2Y3M表示2年3个月)。 - 接收类型的选择:你可以用任意
std::chrono::duration的特化类型(比如seconds、minutes、hours)来接收结果,库会自动将解析到的多单位时长转换为你指定的单位(比如把PT6M2S转换成362秒)。 - 错误处理:解析完成后检查
istringstream的状态,判断是否解析成功。
如果你的date库版本比较老,建议更新到最新版本,确保%P格式符能正常工作。
内容的提问来源于stack exchange,提问作者Magnus Håkansson
相关产品推荐
相关产品推荐

