如何使用 std::chrono 查找当前工作日?

MHe*_*bes 6 c++ c++-chrono c++20

我只是想使用 C++20 std::chrono 打印当前工作日(当地时间)。

看起来很简单():

#include <chrono>
#include <iostream>

int main() {
  using namespace std::chrono;

  system_clock::time_point now = system_clock::now();
  // system_clock::time_point now = sys_days{June / 26d / 2023y} + 12h;

  weekday wd{floor<days>(now)};

#ifdef _WIN32
  std::cout << wd << "\n";
#else
  std::cout << wd.c_encoding() << " (Sunday = " << Sunday.c_encoding() << ")\n";
#endif

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

然而,这Tue对我来说是打印出来的(今天是星期一)。如果我将评论切换到手动定义的日期(此问题发布于 2023 年 6 月 26 日 -0400),它会打印Mon.

  1. 如何在当前日期正确执行此操作?

  2. 为什么now()日期的行为与sys_days/year_month_day不同?


编辑:我相信这是一个时区问题,正如我的三个链接所暗示的那样。std::chrono但我无法编译它:

#include <chrono>
#include <iostream>

int main() {
  using namespace std::chrono;

  auto now = std::chrono::system_clock::now();
  auto now_local = zoned_time{current_zone(), now}.get_local_time();
  sys_days now_local_in_days{floor<days>(now_local)}; // !!! no constructor available
  weekday wd{now_local_in_days};

#ifdef _WIN32
  std::cout << wd << "\n";
#else
  std::cout << wd.c_encoding() << "\n";
#endif

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

所以我想我要添加:

  1. 如何将 local_time 转换为工作日?

MHe*_*bes 6

我想我明白了。

  1. 如何在当前日期正确执行此操作?

这似乎有效:

#include <chrono>
#include <iostream>

int main() {
  using namespace std::chrono;

  auto now = std::chrono::system_clock::now();
  auto now_local = current_zone()->to_local(now);
  weekday wd{floor<days>(now_local)};

#ifdef _WIN32
  std::cout << wd << "\n";
#else
  std::cout << wd.c_encoding() << "\n";
#endif

  return 0;
}
Run Code Online (Sandbox Code Playgroud)
  1. 为什么 now() 日期的行为与 sys_days/year_month_day 不同?

system_clock::time_points 以 UTC 时间存储。

当你打电话时,now()它的意思是“现在是格林威治标准时间”。从那时起您所做的任何铸造或地板工作均以格林威治标准时间为准。当我写这篇文章时已经很晚了,虽然当地是星期一,但格林威治标准时间已经是星期二了。

当您手动定义时间时,它也采用 UTC 格式,并且完全按原样接受。所以我给它一个星期一的日历日期,隐式使用 GMT,效果很好。

  1. 如何将 local_time 转换为工作日?

往上看。不确定我链接到的帖子(使用 HH 的date库)和 C++20 之间发生了什么变化,但我的最终上述解决方案是有道理的。您使用当前时区将标的物偏移time_since_epoch()4 小时,然后将其缩减为一天/工作日。

回想起来,所有这些都是显而易见的,但我想我会把解释留给后代。