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
,值介于 0s
和 seconds{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
}
我的任务是将一些 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
,值介于 0s
和 seconds{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
}