c++ - 如何在 Windows 上解析 std::put_time("%x") 创建的字符串?
问题描述
初始点
让我们假设 windows 上的第三方组件使用以下函数创建一个表示日期的字符串:
std::string getDate() {
std::tm t = {};
std::time_t now = std::time(nullptr);
localtime_s(&t, &now);
std::stringstream s;
s.imbue(std::locale(""));
s << std::put_time(&t, "%x");
return s.str();
}
根据您的系统区域设置和短日期格式的设置,您会得到类似15.09.2020
or09/15/2020
或15. Sept. 2020
等的字符串。
%x
如cppreferencewrites localized date representation (locale dependent)
所述,这是预期的。
问题
如何将生成的字符串解析std::put_time("%x")
回 a std::tm
(假设相同的语言环境和短日期格式系统设置)?
什么不起作用
STL
std::tm parseDate1(const std::string& date) {
std::tm t = {};
std::istringstream ss(date);
ss.exceptions(std::ifstream::failbit);
ss.imbue(std::locale(""));
ss >> std::get_time(&t, "%x");
return t;
}
不起作用,因为 std::get_time 的实现需要 in 的硬"%d / %m / %y
编码%x
格式xlocime
。
促进
std::tm parseDate2(const std::string& date) {
boost::gregorian::date d;
auto* input_facet = new boost::gregorian::date_input_facet();
input_facet->format("%x");
std::istringstream ss(date);
ss.exceptions(std::ifstream::failbit);
ss.imbue(std::locale(std::locale(""), input_facet));
ss >> d;
return boost::gregorian::to_tm(d);
}
Boost 总是返回1400-Jan-01
,因为%x
似乎根本没有实现解析。
字符串时间
windows上好像没有。这里有一个实现,但编译和集成似乎并不简单。
解决方法
到目前为止我想出的最好的解决方法是使用 Win32 函数EnumDateFormats()
来读取系统DATE_SHORTDATE
格式并将这种格式转换为std::get_time()
语法,因为它不兼容(例如dd.MM.yyyy
需要转换为%d.%m.%Y
for std::get_time()
)。但这似乎容易出错,而不是“正确”的方法......
它似乎也在内部std::put_time()
使用strftime
并且std::get_time()
是“自我实现的”。我本来希望通过使用相同的格式字符串生成的所有内容都std::put_time()
应该是可解析的。std::get_time()
但这似乎并非如此,而且似乎也没有记录在案。还是我错过了什么?
解决方案
Plauger 有一篇著名的帖子,他不会解析“Michaelmas 之后的第 14 天”,标准委员会不能让他这样做。你可以做的是put_time
一个已知的日期,例如 71/2/1,并尝试剖析结果以重新创建一个详细的模式,以便以后用于解析。
推荐阅读
- python - 路径中的连接 使用 Unet 进行深度学习
- r - 如何处理 R 函数中的多个输出?
- c - 如何使 ALE 与混合的 Windows/Cygwin 和 tricore-gcc 一起使用?
- typescript - 在 ES6 TypeScript API 中使用 PIXI.JS 依赖项
- java - 序列化和反序列化中用小写字母响应 Jackson
- python - pandas 如何逐行迭代地计算一个类别的实例并在另一个类别出现时重置它们?
- python - 在单独的行中创建提交、作者、时间戳、文件日志的列
- scala - CanBuildFrom 和类型上限参数
- ocaml - OCaml 递归函数:子列表元素乘以它们在列表中的位置,然后求和
- sql - SQL 两个 JOINS 同一张表不同的值