解析日期字符串以从时间戳中删除小时,分钟和秒
假设我从Web服务器接收到要解析的字符串。该字符串包含格式为YYYY-MM-DD
的日期。 我想要的是将其转换为表示当天开始的时间戳,因此我不需要秒,分钟和小时。解析日期字符串以从时间戳中删除小时,分钟和秒
作为一个虚拟示例,我试图提取当前日期的时间戳,一旦转换为YYYY-MM-DD
格式。下面的代码:
#include <chrono>
#include <iomanip>
#include <iostream>
#include <sstream>
int main()
{
// Current time at GMT
std::time_t now = std::time(0);
std::tm *now_tm = std::gmtime(&now);
std::ostringstream oss;
// Extract yyyy-mm-dd = %F
oss << std::put_time(now_tm, "%F");
// Use oss to get a date without seconds from
// current time at gmt
std::tm tm;
std::istringstream ss(oss.str());
ss >> std::get_time(&tm, "%F");
std::time_t current_date = std::mktime(&tm);
std::cout << oss.str() << std::endl;
std::cout << "cd: " << current_date << std::endl;
return 0;
}
输出是:
2017-10-19
cd: 1908337984324104
提取的时间戳显然是错误的。使用%F
格式解析2017-10-19
字符串时问题出在哪里?
documentation of std::get_time列出没有转换说明符%F。当检查流标志(你总是应该这样做!)时,它也会告诉转换失败,至少在我的编译器中是这样。
因此,通过用%Y-%m-%d代替它,转换成功。最后,你默认构造了tm变量而不用调零(例如通过值初始化)。当解决这个为好,该代码按预期工作:
#include <chrono>
#include <iomanip>
#include <iostream>
#include <sstream>
int main()
{
// Current time at GMT
std::time_t now = std::time(0);
std::tm *now_tm = std::gmtime(&now);
std::ostringstream oss;
// Extract yyyy-mm-dd = %F
oss << std::put_time(now_tm, "%Y-%m-%d");
// Use oss to get a date without seconds from
// current time at gmt
std::tm tm{ }; // value-initialize!
std::istringstream ss(oss.str());
ss >> std::get_time(&tm, "%Y-%m-%d");
if(!ss) std::cout << "conversion error\n";
else {
std::time_t current_date = std::mktime(&tm);
std::cout << current_date << '\n';
std::cout << "cd: " << current_date << '\n';
}
return 0;
}
你可以做到这一点,而不使用Howard Hinnant's, free, open-source, header-only chrono-extension library离开chrono
型系统的安全性。
#include "date/date.h"
#include <iostream>
int
main()
{
std::istringstream ss{"2017-10-19"};
date::sys_seconds tp;
ss >> date::parse("%F", tp);
std::cout << date::format("%F\n", tp);
using date::operator<<;
std::cout << "cd: " << tp.time_since_epoch() << '\n';
}
date::sys_seconds
是std::chrono::time_point
计数在Unix Timechrono::seconds
。您可以使用%F
直接解析它。您也可以使用相同的格式字符串(%F
)对其进行格式化,并检查底层计数chrono::seconds
。本程序输出:
2017-10-19
cd: 1508371200s
太好了。感谢您的建议。保持我的赞成 – nessuno
非常感谢!我正在查看另一个时间格式化函数的文档,猜测它会是一样的。我错了。 – nessuno