我有一个自定义的Epoc日期,它与STL中的硬编码Epoc不同。我想知道在特定天数之后的新日期。
std::string ReturnDateTimeAsString(long double NumberOfDaysSinceEpoc)
{
std::istringstream iss("1200-01-01.00:00:00"); // My custom Epoc
std::tm Time;
iss >> std::get_time(&Time, "%Y-%m-%d.%H:%M:%S");
std::chrono::system_clock::time_point MyEpoc = std::chrono::system_clock::from_time_t(std::mktime(&Time));
std::chrono::duration<long double, std::ratio<86400, 1>> Days(NumberOfDaysSinceEpoc); // 86400: Seconds in a day
std::chrono::system_clock::time_point DateTime = MyEpoc + Days; // I get the error here!
std::time_t TimeType = std::chrono::system_clock::to_time_t(DateTime);
return std::string(std::ctime(&TimeType));
}
函数参数可以是十进制。例如,如果我将4.25
传递给此函数,我想从中获取字符串"1200-01-05.06:00:00"
(在Epoc之后4天和6小时)。
我在尝试添加Epoc和Days
变量的行中收到以下错误消息。
Cannot convert from 'std::chrono::time_point<std::chrono::system_clock,std::chrono::duration<long double,std::ratio<0x01,0x0989680>>>'
to
'std::chrono::time_point<std::chrono::system_clock,std::chrono::system_clock::duration>'
No suitable user-defined conversion from
"std::chrono::time_point<std::chrono::system_clock, std::chrono::duration<long double, std::ratio<1i64, 10000000i64>>>"
to
"std::chrono::system_clock::time_point"
如何修复此代码?
答案 0 :(得分:0)
忽略名称空间,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
的{{1}}转换为基于积分的time_point
。这可以通过time_point
:
time_point_cast
这是否使你的功能正确是另一回事。但是这会使类型系统工作。
使用此date library,我可以很容易地看到,至少在我的系统上,你的时代不是你想要的:
std::chrono::system_clock::time_point DateTime =
std::chrono::time_point_cast<std::chrono::system_clock::duration>(MyEpoc + Days);
这为纪元输出:
#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
,至少在我的系统上,可能无效回到1200-01-01。
事实证明,在我的系统上,此操作受mtkime
秒(numeric_limits<int32_t>::min()
)的限制。而-2'147'483'648s
是1901-12-13 20:45:52。尝试在此之前设置纪元,我的系统(OS X)就会崩溃。
使用此date library,我已经简化了您的功能,并且它正在测试,假设您在UTC时区中设定了您的纪元(如果没有,则很容易更改):
sys_days{1970_y/1/1} - 2'147'483'648s
输出:
#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
并获得相同的输出。
如果您更喜欢输出字符串的其他格式,那也很容易。更多详情请访问以下链接: