自一周开始以来的秒数?

number of seconds since start of week?

本文关键字:一周 开始      更新时间:2023-10-16

我一直在尝试霍华德的日期库。有许多示例可以获取自某一天午夜以来的秒数,但不是自该天所属的一周开始以来的秒数。按照以下示例,我生成了以下代码:

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?

但结果是错误的。例如,tp:

2018-10-25T11:26:00.397836134Z

将产生 DP:

2018-10-25T00:00:00.000000000Z 

这是 25 日的午夜,而不是 21 日的午夜。产生正确输出的最直接方法是什么?

我已经对user1095108的自我答案投了赞成票,因为它得到了正确的答案。 但我想添加更多信息,这些信息并不完全适合评论。

"本周开始"并没有得到普遍同意。 一些国家将星期一作为一周的开始,ISO标准也是如此。 其他国家将星期日视为一周的开始。 该库试图在这个问题上尽可能保持中立。

即使你确定了你的目标工作日,你也需要确定在找到一周开始的第二个工作日时你想考虑的星球上的哪个地方。

从您的代码来看,我将假设:

  1. 一周从星期日开始。
  2. 我们希望根据 UTC 找到一周的开始。

对于以下代码,假设:

using namespace date;
using namespace std::chrono;

只是为了防止事情变得过于冗长。

我要做的第一件事是以秒的精度将输入转换为time_point

auto tp = floor<seconds>(system_clock::now());

然后,为了进行工作日的计算,例如查找输入tp的工作日,将需要另一个精度为天time_point

auto dp = floor<days>(tp);

您可以直接从日精度time_point(dp(构造weekday,而不是通过更昂贵的计算来形成year_month_weekday

weekday{dp}

然后(如您所显示的(减去自本周开始以来的天数:

dp -= weekday{dp} - Sunday;

现在您有两个time_point:您的输入和一周的开始。 您可以简单地减去它们以获得一周的秒数:

std::cout << tp - dp << 'n';

现在floor<weeks>(tp)没有给你想要的结果的原因是system_clock是Unix时间。 此度量值计算自 1970-01-01 00:00:00 UTC 以来的时间(忽略闰秒(。 1970-01-01是一个星期四。 因此,将system_clock::time_point截断为weeks精度会将"一周的开始"定义为星期四。

为了获得更多乐趣,请以当地时间计算自一周开始以来的秒数,这可能涉及夏令时调整。 在这种情况下,计算有多个正确答案:您是计算物理秒数,这使得某些星期没有正好 604800,还是计算"历秒"? 例如,2018 年 11 月 4 日 1:00 EST(美国/New_York(是一周中的 1 小时还是 2 小时? 一旦您决定哪个是正确的答案,这个库就可以计算它。

霍华德的大部分日历计算似乎都是基于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()。会不会是std::chrono缺乏对date::weeks的支持,date::weeks演员阵容不起作用?不过,霍华德的date::floor()给出了与std::chrono::floor()相同的输出。