Игнорирование пространств имен, MyEpoc
имеет тип system_clock::time_point
и Days
имеет тип duration<long double, ratio<86400>>
. Сумма этих двух типов будет иметь тип:
time_point<system_clock, duration<long double, system_clock::period>>
Вы пытаетесь присвоить этот тип к:
system_clock::time_point
, который то же самое:
time_point<system_clock, system_clock::duration>
system_clock::duration
указан для некоторого подписанного интегрального типа (обычно long long
). Таким образом, вся проблема заключается в попытке конвертировать long double
на основе time_point
в интегральный time_point
. Это может быть сделано с time_point_cast
:
std::chrono::system_clock::time_point DateTime =
std::chrono::time_point_cast<std::chrono::system_clock::duration>(MyEpoc + Days);
ли, что делает ваша функция правильно или нет, это другой вопрос. Но это приводит к тому, что система типов работает.
Используя этот date library, я могу легко видеть, что по крайней мере на моей системе, ваша эпоха не то, что вы хотите быть:
#include "date.h"
std::string
ReturnDateTimeAsString(long double NumberOfDaysSinceEpoc)
{
using namespace std;
using namespace std::chrono;
istringstream iss("1200-01-01.00:00:00"); // My custom Epoc
tm Time;
iss >> get_time(&Time, "%Y-%m-%d.%H:%M:%S");
system_clock::time_point MyEpoc = system_clock::from_time_t(mktime(&Time));
{
using namespace date;
std::cout << MyEpoc << '\n';
}
duration<long double, ratio<86400, 1>> Days(NumberOfDaysSinceEpoc); // 86400: Seconds in a day
system_clock::time_point DateTime = time_point_cast<system_clock::duration>(MyEpoc + Days); // I get the error here!
time_t TimeType = system_clock::to_time_t(DateTime);
return string(ctime(&TimeType));
}
Это выходы для эпохи:
1969-12-31 23:59:59.000000
mtkime
, по крайней мере, в моей системе, возможно, недействителен к 1200-01-01.
Как оказалось, в моей системе эта операция ограничена numeric_limits<int32_t>::min()
секундами (-2'147'483'648s
). И sys_days{1970_y/1/1} - 2'147'483'648s
- 1901-12-13 20:45:52. Попробуйте установить эпоху раньше, чем моя система (OS X).
Используя этот date library, я упростил вашу функцию, и тестирует правильно, при условии, что вы хотели вашу эпоху в UTC часовой пояс (если нет, то можно легко изменить, что):
#include "date.h"
using days_ld = std::chrono::duration<long double, std::ratio<86400>>;
std::string
ReturnDateTimeAsString(days_ld Days)
{
using namespace std;
using namespace std::chrono;
using namespace date;
constexpr auto MyEpoc = sys_days{1200_y/1/1};
auto DateTime = round<seconds>(MyEpoc + Days);
ostringstream out;
out << DateTime;
return out.str();
}
int
main()
{
std::cout << ReturnDateTimeAsString(days_ld{4.25}) << '\n';
}
Это выводит:
1200-01-05 06:00:00
Я взял на себя смелость округления вашего long double
входа в ближайший seconds
. Если вы предпочитаете что-то более тонкие, скажем milliseconds
, что простое изменение:
auto DateTime = round<milliseconds>(MyEpoc + Days);
который изменяет вывод:
1200-01-05 06:00:00.000
Или:
auto DateTime = round<minutes>(MyEpoc + Days);
который изменяет вывод :
1200-01-05 06:00
Изменяя аргумент функции на желаемый тип продолжительности (days_ld
), теперь ваша функция более безопасна и более гибкая. Например ваш клиент теперь может также ввести std::chrono::hours
:
using namespace std::chrono_literals;
std::cout << ReturnDateTimeAsString(102h) << '\n';
и получить одинаковый выход.
Если вы предпочитаете какой-либо другой формат для выходной строки, это тоже очень просто. Более подробная информация по этим ссылкам:
http://howardhinnant.github.io/date/date.html
https://github.com/HowardHinnant/date/wiki