这有效:
year_month_day day() {
return year_month_day(floor<days>(
zoned_time{
zone,
system_clock::now()
}.get_local_time()));
}
但是我需要,floor()
如上所述zoned_time
- 因为这是在持续时间上模板化的,我希望能够将其或的结果降到最低,即执行以下now()
操作:
year_month_day day2() {
return year_month_day(
zoned_time{
zone,
floor<days>(system_clock::now())
}.get_local_time());
}
因此,我很困惑为什么当我尝试这样做时会出现以下错误 -zoned_time
上面的内容不应该以天为单位,这样才能很好地转换为year_month_day
?
error: no matching function for call to ‘std::chrono::year_month_day::year_month_day(std::chrono::local_time<std::chrono::duration<long int> >)’
48 | }.get_local_time());
我正在使用g++ (GCC) 14.2.1 20240912 (Red Hat 14.2.1-3)
(称为c++
)和-std=gnu++20
。
year_month_day
可以从精度为 天 的时间点转换。该时间点可以基于system_clock
或local_t
。但无论哪种情况,其精度都必须days
为。也可以进行反向转换,转换后的结果与原始结果的时间点完全相同。这被称为无损转换。信息得以保存。
如果允许从精度高于 的时间点进行转换
days
,例如seconds
,那么这将是有损转换,并违反了 chrono 的基本设计原则之一:您不能隐式地丢失信息。您必须使用诸如 之类的表达式明确请求有损转换floor
。此子表达式:
根据创建
days
-precision 。到目前为止一切顺利。time_point
system_clock
此子表达式:
取
days
-precisiontime_point
并将关联time_zone
的 UTC 偏移量添加到其中以计算本地时间。IANA 时区数据库中的 UTC 偏移量单位为seconds
。如果将-precision添加seconds
到其中,结果将为-precision 。并且此-precision不能直接转换为。days
time_point
seconds
time_point
seconds
time_point
year_month_day
以上都是类型系统将潜在的运行时错误转化为编译时错误。如果允许有损转换,有时会给出错误的答案。
例如,假设 UTC 偏移量为 5 小时,当前
system_clock
时间 (UTC) 为 20 小时。正确的当地时间(在底线之前)是第二天的 01:00:floor<days>(20h + 5h)
给出第二天。但是如果有人计算的话,
floor<days>(20h) + 5h
你会得到同一天的 05:00(一次性错误)。您正在实例化
zoned_time
而不指定模板参数,这意味着将使用其推导指南。 在这种情况下,推导指南是:这
zoned_time
至少会给出秒级的分辨率,这意味着您的天级分辨率将被覆盖。这在您的第一个解决方案中不是问题,因为floor
稍后会应用。请注意,即使编译通过(或者您明确指定了模板参数),这也是不正确的,因为通过剥离小时和分钟信息,您会阻止时区计算正常工作。