Is a separator character required to parse a string using std::get_time? I can't find a reference to say that it is. I'm trying to parse an ISO date/time string such as "20140105T123456" - for example:
For example,
#include <iostream>
#include <sstream>
#include <locale>
#include <iomanip>
#include <ctime>
int main(int argc, char* argv[])
{
std::tm t = { 0 };
// fails
std::istringstream ss("20141105T123456");
ss >> std::get_time(&t, "%Y%m%dT%H%M%S");
// works
//std::istringstream ss("2014 11 05 T 12 34 56");
//ss >> std::get_time(&t, "%Y %m %d T %H %M %S");
std::ostringstream os;
std::cout << std::put_time(&t, "%c") << std::endl;
}
I'm using Visual Studio 2013. I tried to build on Linux but the latest version of GCC I have is 4.7.3 which doesn't appear to support get_time yet.
Silly mistake on my part or are separators required?
According to the description of second parameter of std::get_time
, separators are not required.
The format string consists of zero or more conversion specifiers, whitespace characters, and ordinary characters (except %). Each ordinary character is expected to match one character in the input stream in case-insensitive comparison. Each whitespace character matches arbitrary whitespace in the input string. Each conversion specification begins with % character, optionally followed by E or O modifier (ignored if unsupported by the locale), followed by the character that determines the behavior of the specifier. The format specifiers match the POSIX function strptime()
On my Mac, I use clang++(Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
) to compile your code, and run the program, the output is: Sun Nov 5 12:34:56 2014
. Acctually, I have gcc 4.8.2 installed, but it doesn't support the std::get_time
and std::put_time
. Then I search the implementation status for this function, and find that is not implemented in GCC 4.8.0
It did fail in VS2013, after calling std::get_time
, all the elements in t are just 0. Format specifiers don't do what's expected here on Windows. It's not your mistake.
The reference to the POSIX strptime() function in the standard is causing some confusion. The POSIX standard specifies that the conversion operators are separated by non-alpha characters.
The application shall ensure that there is white-space or other non-alphanumeric characters between any two conversion specifications.
The GLIBC version of strptime (and, IMO, any sane implementation) does not require these separators. [http://man7.org/linux/man-pages/man3/strptime.3.html -- see the Notes section.]
Requiring separators makes it impossible to parse conforming ISO-8601 date/time basic formats. As C++ is also an ISO standard, its strptime() function should be able to parse this format.
I think the std::get_time() documentation needs to be clarified to explicitly state that separators shall not be required and justify that statement by pointing to ISO-8601. It should further be clarified that the POSIX strptime() standard only specifies the conversion specifiers that are required to be supported by a conforming implementation.
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