我一直在尝试霍华德的日期库。有许多示例可以获取自某一天的午夜以来的秒数,但自该天所属的星期开始以来没有秒数。按照示例,我生成了以下代码:
My_Topic
但是结果是错误的。例如,tp:
using timepoint_t = std::chrono::time_point<
std::chrono::system_clock,
std::chrono::nanoseconds
>;
timepoint_t tp; // input
auto dp = std::chrono::floor<date::weeks>(tp); // output, should point to start of week?
将产生dp:
2018-10-25T11:26:00.397836134Z
,即25日的午夜,而不是21日的午夜。产生正确输出的最直接方法是什么?
答案 0 :(得分:8)
我已对user1095108的自我回答进行了投票,因为它获得了正确的答案。但是我想添加更多的信息,而这些信息可能都不适合发表评论。
“一周的开始”尚未得到普遍同意。一些国家/地区将星期一作为一周的开始,ISO标准也是如此。其他国家/地区则将星期日视为一周的开始。该库试图在此问题上尽可能保持中立。
即使您确定了要在哪个工作日定位,也需要确定在寻找一周的第二个星期时要考虑的星球上的位置。
从您的代码来看,我假设:
对于以下代码,假定:
using namespace date;
using namespace std::chrono;
只是为了防止事情变得过于冗长。
我要做的第一件事是以秒为单位的精度将输入转换为time_point
:
auto tp = floor<seconds>(system_clock::now());
然后,为了进行工作日计算,例如查找输入tp
的工作日,一个人将需要另一个time_point
,其精度为几天:
auto dp = floor<days>(tp);
您可以直接从日精度weekday
(time_point
)来构建dp
,而不必进行形成year_month_weekday
的更昂贵的计算:>
weekday{dp}
然后(如您所示)减去自一周开始以来的天数:
dp -= weekday{dp} - Sunday;
现在您有两个time_point
:输入内容和一周的开始。您可以简单地减去它们以获得一周中的秒数:
std::cout << tp - dp << '\n';
现在,floor<weeks>(tp)
无法为您提供理想结果的原因是,system_clock
是Unix Time。此度量从1970年1月1日00:00:00 UTC(忽略leap秒)开始计时。 1970-01-01是星期四。因此,将system_clock::time_point
截断为精度weeks
会将“一周的开始”定义为星期四。
要获取更多乐趣,请计算当地时间自星期开始以来的秒数,这可能涉及夏令时调整。在这种情况下,计算有多个正确答案:您是否计算物理秒数,这使某些周的时间不完全是604800,还是计算“日历秒数”?例如,美国时间11月4/2018 1:00(美国/纽约)是一周的1或2个小时?一旦确定了正确的答案,该库即可对其进行计算。
答案 1 :(得分:4)
霍华德的大部分日历计算似乎都基于date:days
。因此,看来您date::weeks
不走运。一种可能的答案是:
auto dp(std::chrono::floor<date::days>(tp));
dp -= date::year_month_weekday(dp).weekday() - date::Sunday;
然后获得秒数作为习惯std::chrono::duration_cast<std::chrono::seconds>(
tp - dp).count()
。难道date::weeks
中的std::chrono
缺少对date::weeks
的支持吗?霍华德的date::floor()
的输出与std::chrono::floor()
相同。