C++ 计算日期,给定自定义Epoc后的天数

C++ 计算日期,给定自定义Epoc后的天数,c++,datetime,chrono,C++,Datetime,Chrono,我有一个自定义的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(&Ti

我有一个自定义的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));
}

如何修复此代码?

忽略名称空间,
MyEpoc
的类型为
system\u clock::time\u point
,而
Days
的类型为
duration
。这两种类型的总和将具有以下类型:

time_point<system_clock, duration<long double, system_clock::period>>
这与:

time_point<system_clock, system_clock::duration>
这是否使您的功能正确是另一回事。但这使类型系统工作起来


使用这个,我可以很容易地看到,至少在我的系统上,您的纪元不是您想要的:

#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));
}
mtkime
,至少在我的系统上,可能在1200-01-01之前无效

事实证明,在我的系统上,此操作受到
数值限制::min()
秒(
-2'147'483'648s
)的限制。和sys_days{1970年y/1/1}-2'147'483'648s1901-12-13 20:45:52。试着将纪元设置得更早,我的系统(OSX)就会崩溃

使用这一点,我简化了您的功能,并且它正在正确测试,假设您打算在UTC时区中使用您的历元(如果不是,很容易更改):

我冒昧地将您的
长双精度
输入四舍五入到最接近的
秒数
。如果您想要更精细的,比如说
毫秒
,这是一个简单的更改:

    auto DateTime = round<milliseconds>(MyEpoc + Days);
或:

通过将函数的参数更改为所需的持续时间类型(
days\ld
),您的函数现在使用起来更安全,也更灵活。例如,您的客户端现在还可以输入
std::chrono::hours

    using namespace std::chrono_literals;
    std::cout << ReturnDateTimeAsString(102h) << '\n';
使用名称空间std::chrono_文本;
标准::cout
#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
#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
    auto DateTime = round<milliseconds>(MyEpoc + Days);
1200-01-05 06:00:00.000
auto DateTime = round<minutes>(MyEpoc + Days);
1200-01-05 06:00
    using namespace std::chrono_literals;
    std::cout << ReturnDateTimeAsString(102h) << '\n';