'Failed trying yo parse Kitchen time with date.h or chronos
I'm developing a C++ timestamp parser that could check if any given string can be a timestamp representation, covering various formats.
I've tested some libraries and finally, I'm using the single header one developed by @howard-hinnant.
The only problem is with the Kitchen format 03:04AM (HH:MM<AM|PM>).
This is the code that I'm using:
#include "date.h"
#include <iostream>
#include <string>
#include <sstream>
int main()
{
std::string const fmt = "%I:%M%p" ;
std::string const time;
std::string const name;
date::fields<std::chrono::nanoseconds> fds {};
std::chrono::minutes offset {};
std::string abbrev;
const std::string in = "3:04a.m.";
std::stringstream ss(in);
std::unordered_map<std::string, std::string> result;
date::from_stream(ss, fmt.c_str(), fds, &abbrev, &offset);
if (!ss.fail())
{
if (fds.has_tod && fds.tod.in_conventional_range())
{
std::cout << "result hour " << std::to_string(fds.tod.hours().count()) << std::endl;
std::cout << ". minutes " << std::to_string(fds.tod.minutes().count())<< std::endl;
std::cout << ". seconds " << std::to_string(fds.tod.seconds().count())<< std::endl;
}
}
else
{
std::cout << "failed" << std::endl;
}
}
What I'm doing wrong, the code works great with other formats? is there a chance that parsing a date requires more fields in order to process it fully (year, month, day)?
Hope I made myself clear, thanks in advance!
Solution 1:[1]
In the "C" locale, %p
refers to one of AM or PM. You have "a.m.". Removing the '.' works for me.
There is one other caveat: The POSIX spec for strptime specifies that case should be ignored. And my date lib follows the POSIX spec on this. However by default this library forwards to your std::library for this functionality. And some implementations didn't get the memo on this. They may not accept lower case.
If this happens for you, you can work around this std::lib bug by compiling with -DONLY_C_LOCALE
on the command line (or set ONLY_C_LOCALE=1
in your IDE wherever macros are set). This tells the date lib to do the %p parse itself, instead of forwarding to the std::lib. And it will correctly do a case-insensitive parse. However it assumes that the "C" locale is in effect.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Howard Hinnant |