Новый ответ для старого вопроса. Обоснование нового ответа: вопрос был отредактирован из его первоначальной формы, потому что инструменты в то время не обрабатывали точно то, что было задано. И полученный принятый ответ дает тонко другое поведение, чем то, что задавал первоначальный вопрос.
Я не пытаюсь принять принятый ответ. Это хороший ответ. Это просто, что C API - это , поэтому сбивает с толку, что неизбежно произойдут такие ошибки.
Первоначальный вопрос заключался в анализе "Thu, 9 Jan 2014 12:35:34 +0000"
. Настолько ясно, что целью было разобрать временную метку, обозначающую время UTC. Но strptime
(который не является стандартным C или C++, но является POSIX) не анализирует конечное UTC-смещение, указывающее, что это временная метка UTC (она будет отформатировать ее с помощью %z
, но не разобрать ее).
Вопрос был изменен, чтобы узнать о "Thu Jan 9 12:35:34 2014"
. Но вопрос был не, отредактированный, чтобы уточнить, была ли это отметкой времени UTC или отметкой времени в текущем часовом поясе компьютера. Принятый ответ неявно предполагает, что временная метка представляет текущий локальный часовой пояс компьютера из-за использования std::mktime
.
std::mktime
не только преобразует тип поля tm
к последовательному типу time_t
, он также выполняет регулировку смещения от местного часового пояса компьютера к UTC.
Но что, если мы хотим разобрать временную метку UTC в качестве исходного (неотредактированного) вопроса?
Это можно сделать сегодня, используя этот новый, 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);
}
Эта библиотека может разобрать %z
. И date::sys_seconds
просто ЬурейиЙ для:
std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>
вопрос также спрашивает:
Из полученного срока мне нужен доступ к номерам секунд, минут, часов и дней.
Эта часть осталась без ответа. Вот как вы это делаете с this library. В этой части я также буду использовать вторую 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>
обрежет секундную точность time_point
до дней точностиtime_point
. Если вы вычтите предел дня time_point
из tp
, вы останетесь с 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.
POSIX-системы (например, Linux или OSX) имеют ['strptime'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/strptime.html), который анализирует строку в структуре' tm'. К сожалению, он не существует для Windows, но [есть альтернативы] (http://stackoverflow.com/a/321877/440558). –
@JoachimPileborg Поддерживает ли он '+ 0000' в конце? –
@remyabel, на самом деле я ошибся. Этот суффикс не существует. Я обновил вопрос. –