Как разбирать строку даты в c ++ 11 std :: chrono time_point или подобное?

Рассмотрим историческую строку даты формата:

Thu Jan 9 12:35:34 2014 

Я хочу проанализировать такую ​​строку в виде представления даты C ++, а затем вычислить количество времени, прошедшее с тех пор.

Из полученной продолжительности мне нужен доступ к количеству секунд, минут, часов и дней.

Можно ли это сделать с новым пространством имен std::chrono C ++ 11? Если нет, то как мне это сделать сегодня?

Я использую g ++ – 4.8.1, хотя, по-видимому, ответ должен быть нацелен только на спецификацию C ++ 11.

     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 до версии 5 не реализует std::get_time . Вы также должны иметь возможность написать:

     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)); 

    Новый ответ на старый вопрос. Обоснование нового ответа: вопрос был отредактирован из его первоначальной формы, потому что инструменты в то время не обрабатывали точно то, что было задано. И полученный принятый ответ дает тонко другое поведение, чем то, что задавал первоначальный вопрос.

    Я не пытаюсь принять принятый ответ. Это хороший ответ. Просто API C настолько запутывает, что неизбежно произойдет такая ошибка.

    Первоначальный вопрос состоял в том, чтобы разобрать "Thu, 9 Jan 2014 12:35:34 +0000" . Настолько ясно, что целью было разобрать временную метку, обозначающую время UTC. Но strptime (который не является стандартным C или C ++, но является POSIX) не анализирует отстающее UTC-смещение, указывающее, что это timestamp UTC (она будет отформатировать ее с помощью %z , но не проанализировать ее).

    Затем вопрос редактировался, чтобы спросить о "Thu Jan 9 12:35:34 2014" . Но вопрос не был изменен, чтобы уточнить, была ли это отметка времени UTC или отметка времени в текущем локальном часовом поясе компьютера. В принятом ответе подразумевается, что timestamp представляет текущий локальный часовой пояс компьютера из-за использования std::mktime .

    std::mktime не только преобразует тип поля tm в серийный тип time_t , он также выполняет настройку смещения от локального часового пояса компьютера до UTC.

    Но что, если мы хотим разобрать временную метку UTC в качестве исходного (неотредактированного) вопроса?

    Это можно сделать сегодня, используя эту новую бесплатную библиотеку с открытым исходным кодом .

     #include "date.h" #include  #include  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); } 

    Эта библиотека может анализировать %z . И date::sys_seconds – это всего лишь typedef для:

     std::chrono::time_point 

    Вопрос также задает вопрос:

    Из полученной продолжительности мне нужен доступ к количеству секунд, минут, часов и дней.

    Эта часть осталась без ответа. Вот как вы это делаете с этой библиотекой . Для этой части я также собираюсь использовать вторую библиотеку "chrono_io.h" только для "chrono_io.h" :

     #include "chrono_io.h" #include "date.h" #include  #include  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(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 обрезает секундную time_point precision_point с точностью до точки time_point . Если вы time_point из tp time_point precision_point_point, вы time_point с duration которая представляет время с полуночи (UTC).

    Заводская функция make_time принимает любую duration (в данном случае время с полуночи) и создает поле типа {hours, minutes, seconds} с геттерами для каждого поля. Если продолжительность имеет точность мельче, чем секунды, этот тип поля также будет иметь геттер для субсекунд.

    Наконец, используя "chrono_io.h" , можно просто распечатать все эти длительности. Этот пример выводит:

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

    [86400]s представляет единицы duration с точностью до суток. Итак, 2014-01-09 - 16079 дней после 1970-01-01.

    Это скорее C-ish и не столь изящное решение, как ответ Simple, но я думаю, что это может сработать. Этот ответ, вероятно, неверен, но я оставлю его, поэтому кто-то может внести исправления.

     #include  #include  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; } 
    Давайте будем гением компьютера.