How to parse a date string into a c++11 std::chrono time_point or similar?

std::get_time
std chrono cppreference
std chrono time of day
std::chrono::system_clock::now
c parse iso 8601
std::chrono::steady_clock
time_point to string
std parse

Consider a historic date string of format:

Thu Jan 9 12:35:34 2014

I want to parse such a string into some kind of C++ date representation, then calculate the amount of time that has passed since then.

From the resulting duration I need access to the numbers of seconds, minutes, hours and days.

Can this be done with the new C++11 std::chrono namespace? If not, how should I go about this today?

I'm using g++-4.8.1 though presumably an answer should just target the C++11 spec.

std::tm tm = {};
std::stringstream ss("Jan 9 2014 12:35:34");
ss >> std::get_time(&tm, "%b %d %Y %H:%M:%S");
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));

GCC prior to version 5 doesn't implement std::get_time. You should also be able to write:

std::tm tm = {};
strptime("Thu Jan 9 2014 12:35:34", "%a %b %d %Y %H:%M:%S", &tm);
auto tp = std::chrono::system_clock::from_time_t(std::mktime(&tm));

std::chrono::parse, Consider a historic date string of format: Thu Jan 9 12:35:34 2014 I want to I tried something like this: using clock = std::chrono::system_clock; clock::​time_point  Consider a historic date string of format: Thu Jan 9 12:35:34 2014 I want to parse such a string into some kind of C++ date representation, then calculate the amount of time that has passed since

New answer for old question. Rationale for the new answer: The question was edited from its original form because tools at the time would not handle exactly what was being asked. And the resulting accepted answer gives a subtly different behavior than what the original question asked for.

I'm not trying to put down the accepted answer. It's a good answer. It's just that the C API is so confusing that it is inevitable that mistakes like this will happen.

The original question was to parse "Thu, 9 Jan 2014 12:35:34 +0000". So clearly the intent was to parse a timestamp representing a UTC time. But strptime (which isn't standard C or C++, but is POSIX) does not parse the trailing UTC offset indicating this is a UTC timestamp (it will format it with %z, but not parse it).

The question was then edited to ask about "Thu Jan 9 12:35:34 2014". But the question was not edited to clarify if this was a UTC timestamp, or a timestamp in the computer's current local timezone. The accepted answer implicitly assumes the timestamp represents the computer's current local timezone because of the use of std::mktime.

std::mktime not only transforms the field type tm to the serial type time_t, it also performs an offset adjustment from the computer's local time zone to UTC.

But what if we want to parse a UTC timestamp as the original (unedited) question asked?

That can be done today using this newer, free open-source library.

#include "date.h"
#include <iostream>
#include <sstream>

int
main()
{
    using namespace std;
    using namespace date;
    istringstream in{"Thu, 9 Jan 2014 12:35:34 +0000"};
    sys_seconds tp;
    in >> parse("%a, %d %b %Y %T %z", tp);
}

This library can parse %z. And date::sys_seconds is just a typedef for:

std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>

The question also asks:

From the resulting duration I need access to the numbers of seconds, minutes, hours and days.

That part has remained unanswered. Here's how you do it with this library. For this part I'm also going to use a second header-only library "chrono_io.h":

#include "chrono_io.h"
#include "date.h"
#include <iostream>
#include <sstream>

int
main()
{
    using namespace std;
    using namespace date;
    istringstream in{"Thu, 9 Jan 2014 12:35:34 +0000"};
    sys_seconds tp;
    in >> parse("%a, %d %b %Y %T %z", tp);
    auto tp_days = floor<days>(tp);
    auto hms = make_time(tp - tp_days);
    std::cout << "Number of days    = " << tp_days.time_since_epoch() << '\n';
    std::cout << "Number of hours   = " << hms.hours() << '\n';
    std::cout << "Number of minutes = " << hms.minutes() << '\n';
    std::cout << "Number of seconds = " << hms.seconds() << '\n';
}

floor<days> truncates the seconds-precision time_point to a days-precision time_point. If you subtract the days-precision time_point from tp, you're left with a duration that represents the time since midnight (UTC).

The factory function make_time takes any duration (in this case time since midnight) and creates a {hours, minutes, seconds} field type with getters for each field. If the duration has precision finer than seconds this field type will also have a getter for the subseconds.

Finally, using "chrono_io.h", one can just print out all of these durations. This example outputs:

Number of days    = 16079[86400]s
Number of hours   = 12h
Number of minutes = 35min
Number of seconds = 34s

The [86400]s represents the units of the duration that has days-precision. So 2014-01-09 is 16079 days after 1970-01-01.

C and C++ XML Data Bindings, How to parse a date string into a c++11 std::chrono time_point or similar? Questions: Consider a historic date string of format: Thu Jan 9 12:35:34 2014 I want to parse such a string into some kind of C++ date representation, then calculate the amount of time that has passed since then. From the resulting duration I need access to the numbers of seconds, minutes, hours and days. Can

This is rather C-ish and not as elegant of a solution as Simple's answer, but I think it might work. This answer is probably wrong but I'll leave it up so someone can post corrections.

#include <iostream>
#include <ctime>

int main ()
{
  struct tm timeinfo;
  std::string buffer = "Thu, 9 Jan 2014 12:35:00";

  if (!strptime(buffer.c_str(), "%a, %d %b %Y %T", &timeinfo))
    std::cout << "Error.";

  time_t now;
  struct tm timeinfo2;
  time(&now);
  timeinfo2 = *gmtime(&now);

  time_t seconds = difftime(mktime(&timeinfo2), mktime(&timeinfo));
  time(&seconds);
  struct tm result;
  result = *gmtime ( &seconds );
  std::cout << result.tm_sec << " " << result.tm_min << " "
            << result.tm_hour << " " << result.tm_mday;
  return 0;
}

C measure time in milliseconds, A character sequence in the format string that begins with a % but does not match one of the conversion specifiers below is interpreted as  How to parse a date string into a c++11 std::chrono time_point or similar? (2) Consider a historic date string of format: Thu Jan 9 12:35:34 2014 I want to parse such a string into some kind of C++ date representation, then calculate the amount of time that has passed since then.

Get the date c, In other words, by leveraging strong typing in C/C++, your XML data meets XML date, string or #import "custom/struct_tm_date.h" to use struct tm for xsd__date This means that <g:name xmlns:g="urn:graph"> is parsed as an instance of a A C++11 std::chrono::system_clock::time_point type is mapped to the built-in  Parse date strings? How to parse a date string into a c++11 std::chrono time_point or similar? Is there a way to find the first string that matches a DateTime format string? SimpleDateFormat producing wrong date time when parsing “YYYY-MM-dd HH:mm” Parsing time string in Python

C++ Core Guidelines, A duration is, like a time_point, just a puffed-up arithmetic type. Implementations in which std::time_t is a 32-bit signed integer (many historical of four different implementations for parsing an integer from a string. C++11, the best way to measure elapsed time in C++ is by using the chrono library which deal with time. If from_stream fails to parse everything specified by the format string, or if insufficient information is parsed to specify a complete result, or if parsing discloses contradictory information, is. setstate (std:: ios_base:: failbit) is called.

C++ Standard Library, DateTime (1999, 1, 13, 3, 57, 32, 11) ' Year gets 1999. struct date dt; ParseExact() methods for converting a string-based date to a System. The encoding of calendar time in std::time_t is unspecified, but most systems conform to You can alter the data storage of a data type by using them. std::chrono::​time_point). Self-explanatory code follows which first creates a std::tm corresponding to 10-10-2012 12:38:40, converts that to a std::chrono::system_clock::time_point, adds 0.123456 seconds, and then prints that out by converting back to a std::tm.

In other words, what would you like your code to look like in 5 years' time, given that you Date read_date(istream& is); // read date from istream Date std::​chrono::duration types (C++11) helps making the unit of time duration explicit. The assumption that the pointer to char pointed to a C-style string (a  Attempts to parse the input stream is into the time point tp according to the format string fmt. Behaves as an UnformattedInputFunction, except that it has an unspecified effect on is. gcount (). After constructing and checking the sentry object, attempts to parse the input stream is into tp according to the format string fmt.

Comments
  • POSIX systems (like Linux or OSX) have a strptime that parses a string into a tm structure. Unfortunately it doesn't exist for Windows, but there are alternatives.
  • @JoachimPileborg Does it support the +0000 at the end, though?
  • @remyabel, actually I was mistaken. That suffix does not exist. I've updated the question.
  • That's good, because the timezone suffix doesn't seem to be supported. :)
  • Note that chrono was not designed with calendar functionality in mind, so associating a time_point with an actual date is not at the core of its functionality. Boost tried to address this in its Date Time library which predates Chrono. Unfortunately, those two libraries don't go together as smoothly as one might wish.
  • But get_time() is not implemented yet on gcc?
  • @SChepurin it might not be, but it's in the C++ spec.
  • According to the bug 54354 at gcc this is solved in gcc 5. Little bit late for a C++11 feature.
  • @Xaqq std::tm t{}; // should do
  • @einpoklum, should work since gcc 5.0. I've tested on gcc 5.4 (that is in current stable Ubuntu 16.04).