C# 到 C++:将 C# 时间计算转换为 C++ chrono

C# to C++: Convert C# Time calculation to C++ chrono

我的任务是将一些 C# 代码转换为 C++,但我遇到了 chrono 问题。目标是将时间舍入为可变时间跨度。

C#:

int iRoundTo = 30; // can be 45 or other variable value, not a const
DateTime dt = Floor(DateTime.Now, new TimeSpan(0, 0, 0, iRoundTo));

我找到了 const iRoundTo 的解决方案,但这不是我要找的。 如何使用 std::chono?

将其转换为 C++

C++:

std::chrono::seconds diff(iRoundTo);
auto dt = std::chrono::floor<diff>(Now);

由于编译错误,这无法正常工作。

谢谢。

我对这个答案做了一些猜测,但我的猜测是你想将当前时间截断到当前半分钟的底部(在 iRoundTo == 30 的情况下)。

如果我是对的,只要 iRoundTo 是一个编译时常量,这很容易做到。

#include <chrono>
#include <iostream>

int
main()
{
    using RoundTo = std::chrono::duration<int, std::ratio<30>>;
    auto Now = std::chrono::system_clock::now();
    auto dt = std::chrono::floor<RoundTo>(Now);
    std::cout << dt << '\n';
}

上面创建了一个新的持续时间类型,长度为 30 秒。然后它获取当前时间并将其下限(向下截断)到前一个半分钟单位。然后打印出结果。 print 之前的所有内容都适用于 C++17。打印(最后一行)需要 C++20。

我的示例输出:

2022-01-18 01:45:30

上面的代码也可以在 C++17 之前工作,但在这种情况下,您需要找到自己的 floor(例如 date.h)或使用 std::chrono::duration_cast截断为零。

更新

在下面的评论中,解释说 iRoundTo 不是 编译时常量,但始终表示秒的倍数。在这种情况下,我将分两步进行:

int iRoundTo = 30;
auto Now = std::chrono::system_clock::now();

// First truncate to seconds
auto dt = std::chrono::floor<std::chrono::seconds>(Now);
// Then subtract of the modulus according to iRoundTo
dt -= dt.time_since_epoch() % iRoundTo;

子表达式 dt.time_since_epoch() % iRoundTo 的类型为 seconds,值介于 0sseconds{iRoundTo} - 1s 之间。

无法使用最新的工具(std::format 和 << overload 似乎都需要相当新的工具)我已经对其进行了测试 only so far(如果可以测试请编辑进一步):

#include <chrono>
#include <iostream>
#include <ctime>
#include <iomanip>
//#include <format>

int main() {
    int roundTo = 15;
    auto dt = std::chrono::floor<std::chrono::seconds> (std::chrono::system_clock::now());
    dt -= dt.time_since_epoch() % roundTo;
    std::time_t t = std::chrono::system_clock::to_time_t(dt);
    std::cout << std::ctime(&t); // Using <ctime>
    std::cout << std::put_time(std::localtime(&t), "%Y-%m-%e %H:%M:%S") << '\n'; // Using <iomanip>
    //std::cout << "date: " << std::format("%Y-%m-%e %H:%M:%S", dt) << '\n'; // Using <format>
    //std::cout << "date: " << std::format("{%Y-%m-%e %H:%M:%S}", dt) << '\n'; // Using newer <format>
    //std::cout << dt << '\n'; // Using << overload
}