gpt4 book ai didi

c++ - C++:将unix时间戳记为UTC月份

转载 作者:行者123 更新时间:2023-12-02 10:13:07 26 4
gpt4 key购买 nike

假设我有一个unix时间戳

int timestamp=1594386202;
我想写一个函数
int floor_to_month_utc(int timestamp);
将时间戳记到相应月份的开始(以UTC为单位)。在此示例中,该函数应满足 1593561600 == floor_to_month_utc(1594386202),因为 1594386202对应于 2020-07-10T13:03:22+00:00 UTC时间,而 1593561600是相应月份 2020-07-01T00:00:00+00:00的开始。
如何在C++中做到这一点? (实际上,我还需要当前时间戳到下个月的时间戳,但是我想如果可以给我提示如何实现发言权功能,我可以自己写)

最佳答案

正如Alan Birtles在注释中指出的那样,这可以在C++ 20中轻松实现:

#include <chrono>

int
floor_to_month_utc(int timestamp)
{
using namespace std::chrono;

sys_seconds tp{seconds{timestamp}};
year_month_day ymd = floor<days>(tp);
sys_seconds result = sys_days{ymd.year()/ymd.month()/1};
return result.time_since_epoch().count();
}
说明:
第一步是将输入放入 <chrono>类型系统。可以理解, timestamp是自1970-01-01 00:00:00 UTC以来的秒数(不包括leap秒)。这也称为 Unix Timestd::chrono::sys_seconds是与这些语义相对应的C++ 20类型。因此, sys_seconds tp{seconds{timestamp}};首先将 timestamp转换为持续时间 seconds,然后再转换为 time_point sys_seconds
下一个必须意识到这是日历计算,而不是时间计算。所使用的日历是民用日历,它以C++ 20 <chrono>建模。因此,下一步是将 time_point tp转换为民用日历中的一天:
year_month_day ymd = floor<days>(tp);
floor<days>会将截断精度从 tp截断为 days精度(自1970-01-01 00:00:00 UTC以来的天数)。 ymd是一种 {year, month, day}数据结构,是从 days -precision time_point转换而来的,类型为 std::chrono::year_month_dayymdfloor<days>(tp)都包含完全相同的信息。但是信息存储在两种不同的数据结构中: {year, month, day}{count of days}
下一步是查找 ymd所指的一年中第一个月的第一天。这只是表达式 ymd.year()/ymd.month()/1
可以使用以下方法将其转换回 {count of days}数据结构:
sys_days{ymd.year()/ymd.month()/1}
std::chrono::sys_days只是表达式 floor<days>(tp)的类型的类型别名,其类型为:
time_point<system_clock, days>
接下来,将 sys_days数据结构隐式转换为 seconds -precision,然后从该数据结构中提取并返回整数。
preview of the C++20 <chrono> library is here,可以与C++ 11/14/17一起使用。要将上述功能移植到此预览库,只需添加 "date/date.h"using namespace date;"date/date.h"是仅 header 的库,因此不需要安装。
可以这样执行:
std::cout << floor_to_month_utc(1594386202) << '\n';
输出:
1593561600

将上面的代码与 this answer进行比较很有启发性,它给出了不同的结果:
1593626076
结果不同的原因可以追溯到日历计算和时间计算之间的区别。日历计算是针对某些日历(民用,中文,朱利安(Julian)等)进行的。而按时间顺序的计算仅在固定(常规)时间单位上进行。日历月和年没有固定的时间长度。
C++ 20 <chrono>库可以使用 monthsyears执行按时间顺序的计算。当处理持续数月或数年的物理或生物过程时,有时这是正确的答案。这样的过程并不关心人造日历。因此,在这种情况下,处理几个月和几年的平均长度是有意义的。
这个说法:
floor<months>(sys_seconds{seconds{timestamp}})
只需将自 Unix Time纪元以来的时间分为规则的甚至是几个月,每个月的长度恰好是2,629,746秒(民用月的平均长度)。因此,如果一个人希望按假想的统一月份(如果您愿意的话,可以使用完全不同的日历)按时间顺序进行计算,则此答案是正确的。

关于c++ - C++:将unix时间戳记为UTC月份,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62833167/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com