In the application I'm working on, I receive as an input a datetime in ISO format ( %Y-%m-%dT%H:%M:%SZ ).
I'd like to check that the received string is indeed in the specified format. I wanted to try the Boost DateTime library, which seemed perfect for this task.
However, I am surprised by the behavior of the DateTime parsing. My code is the following:
#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <sstream>
int main()
{
std::string inputDate = "2017-01-31T02:15:53Z";
std::string expectedFormat = "%Y-%m-%dT%H:%M:%SZ";
boost::posix_time::time_input_facet *timeFacet = new boost::posix_time::time_input_facet(expectedFormat);
std::stringstream datetimeStream(inputDate);
datetimeStream.imbue(std::locale(std::locale::classic(), timeFacet));
boost::posix_time::ptime outputTime;
datetimeStream >> outputTime;
if (datetimeStream.fail())
{
std::cout << "Failure" << std::endl;
}
std::cout << outputTime << std::endl;
return 0;
}
When running this program, the output is:
2017-Jan-31 02:15:53
As expected. However if I change the inputDate to an invalid datetime like "2017-01-31T02:15:63Z" (63 seconds should not be accepted), the output will be
2017-Jan-31 02:16:03
Instead of a "Failure" message. I understand the logic behind, but I'd like to enforce a more strict parsing. Moreover, the parsing will still work when using "2017-01-31T02:15:53Z I like Stackoverflow" as the input, which is even stranger considering it doesn't respect the specified format.
So my question is: How to force Boost DateTime to reject strings that are not strictly respecting the format defined in the time_input_facet ?
Thanks
Can you use another free, open-source, header-only date/time library?
#include "date/date.h"
#include <iostream>
#include <sstream>
int
main()
{
std::string inputDate = "2017-01-31T02:15:63Z";
std::string expectedFormat = "%Y-%m-%dT%H:%M:%SZ";
std::stringstream datetimeStream{inputDate};
date::sys_seconds outputTime;
datetimeStream >> date::parse(expectedFormat, outputTime);
if (datetimeStream.fail())
{
std::cout << "Failure" << std::endl;
}
using date::operator<<;
std::cout << outputTime << std::endl;
}
Output:
Failure
1970-01-01 00:00:00
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With