如何用C++标准/第三方库解析以0或缺省表示月末的日期字符串?
解析"最后一天"格式字符串为
std::chrono::year_month_day_last std::chrono::year_month_day_last可以便捷表示某年月的最后一天,下面分别用三种工具实现你需要的解析需求:
Howard Hinnant日期库(C++11+)
这个轻量仅头文件库是C++20 chrono日期组件的前身,对这类场景支持友好。
处理"YYYY-MM-00"格式
先拆分解析年、月、日,判断日为0时构造year_month_day_last:
#include "date/date.h" #include <iostream> #include <sstream> #include <string> int main() { std::string s = "2023-01-00"; date::year_month ym; int day; std::istringstream in(s); in >> date::parse("%Y-%m-%d", ym, day); if (day == 0 && ym.ok()) { auto ymd_last = date::year_month_day_last{ym.year(), date::month_day_last{ym.month()}}; std::cout << ymd_last << '\n'; // 输出:2023/Jan/last } return 0; }
处理"YYYY-MM"格式
直接解析为year_month,再转换为目标类型:
#include "date/date.h" #include <iostream> #include <sstream> #include <string> int main() { std::string s = "2023-01"; date::year_month ym; std::istringstream in(s); in >> date::parse("%Y-%m", ym); if (ym.ok()) { auto ymd_last = date::year_month_day_last{ym.year(), date::month_day_last{ym.month()}}; std::cout << ymd_last << '\n'; // 输出:2023/Jan/last } return 0; }
C++20 std::chrono
C++20原生支持year_month_day_last,结合std::chrono::parse即可实现:
处理"YYYY-MM-00"格式
解析年、月、日字段,判断日为0时构造目标对象:
#include <chrono> #include <iostream> #include <sstream> #include <string> int main() { std::string s = "2023-01-00"; std::chrono::year y; std::chrono::month m; int d; std::istringstream in(s); in >> std::chrono::parse("%Y-%m-%d", y, m, d); if (d == 0 && y.ok() && m.ok()) { std::chrono::year_month_day_last ymd_last{y / std::chrono::month_day_last{m}}; std::cout << ymd_last << '\n'; // 输出:2023/Jan/last } return 0; }
处理"YYYY-MM"格式
解析为year_month后直接构造:
#include <chrono> #include <iostream> #include <sstream> #include <string> int main() { std::string s = "2023-01"; std::chrono::year_month ym; std::istringstream in(s); in >> std::chrono::parse("%Y-%m", ym); if (ym.ok()) { std::chrono::year_month_day_last ymd_last{ym.year() / std::chrono::month_day_last{ym.month()}}; std::cout << ymd_last << '\n'; // 输出:2023/Jan/last } return 0; }
Boost.DateTime库
Boost.DateTime没有直接对应year_month_day_last的类型,但可以通过last_day_of_month工具类实现等价逻辑:
处理"YYYY-MM-00"格式
由于直接解析"00"日会抛出异常,所以拆分字段处理:
#include <boost/date_time/gregorian/gregorian.hpp> #include <iostream> #include <string> int main() { std::string s = "2023-01-00"; int year, month, day; sscanf(s.c_str(), "%d-%d-%d", &year, &month, &day); if (day == 0) { boost::gregorian::year_month ym(year, month); boost::gregorian::last_day_of_month last_day(ym); // 输出语义化标识与实际日期 std::cout << year << "-" << month << "-last (" << last_day.get_date() << ")\n"; } return 0; }
处理"YYYY-MM"格式
解析为year_month后获取当月最后一天:
#include <boost/date_time/gregorian/gregorian.hpp> #include <iostream> #include <sstream> #include <string> int main() { std::string s = "2023-01"; boost::gregorian::year_month ym; std::istringstream in(s); in >> boost::gregorian::date_facet("%Y-%m") >> ym; boost::gregorian::last_day_of_month last_day(ym); std::cout << ym.year() << "-" << ym.month() << "-last (" << last_day.get_date() << ")\n"; return 0; }
内容的提问来源于stack exchange,提问作者ridilculous
相关产品推荐
相关产品推荐

