В спецификации C++20 есть удобный способ сделать это:
using namespace std::chrono;
sys_seconds tp;
ssTimestamp >> parse("%Y-%m-%d %H:%M:%S", tp);
std::time_t time = system_clock::to_time_t(tp);
Ни один поставщик еще не реализовал эту часть C++20, но есть пример реализации здесь, в namespace date
. .
В C++ до C++20 нет поддержки библиотек для выполнения этой операции.
Лучшее, что вы можете сделать, используя только стандартные библиотеки, — это проанализировать поля в tm
с помощью std::get_time
(как показывает ваш вопрос), а затем преобразовать эту структуру {y, m, d, h, M, s}
в time_t
, используя вашу собственную математику и предположение (что в целом верно), что std::time_t
— это время Unix с точностью до секунд.
Вот коллекция общедоступных календарных алгоритмов, которая поможет вам в этом. Это не сторонняя библиотека. Это кулинарная книга для написания собственной библиотеки дат.
Например:
#include <ctime>
std::time_t
to_time_t(std::tm const& tm)
{
int y = tm.tm_year + 1900;
unsigned m = tm.tm_mon + 1;
unsigned d = tm.tm_mday;
y -= m <= 2;
const int era = (y >= 0 ? y : y-399) / 400;
const unsigned yoe = static_cast<unsigned>(y - era * 400); // [0, 399]
const unsigned doy = (153*(m + (m > 2 ? -3 : 9)) + 2)/5 + d-1; // [0, 365]
const unsigned doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096]
return (era * 146097 + static_cast<int>(doe) - 719468)*86400 +
tm.tm_hour*3600 + tm.tm_min*60 + tm.tm_sec;
}
Ссылка выше содержит очень подробное описание этого алгоритма и модульные тесты, чтобы убедиться, что он работает в диапазоне +/- миллионов лет.
Вышеупомянутый to_time_t
по сути является переносимой версией timegm
, поставляемой на платформах Linux и bsd. Эта функция также называется _mkgmtime
в Windows.
person
Howard Hinnant
schedule
04.07.2019