从一周开始算起的秒数?

时间:2018-10-25 11:47:11

标签: c++ date

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

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日的午夜。产生正确输出的最直接方法是什么?

2 个答案:

答案 0 :(得分:8)

我已对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);

您可以直接从日精度weekdaytime_point)来构建dp,而不必进行形成year_month_weekday的更昂贵的计算:

weekday{dp}

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

dp -= weekday{dp} - Sunday;

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

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

现在,floor<weeks>(tp)无法为您提供理想结果的原因是,system_clockUnix 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()相同。