如何使用 date.h 在 C++ 中获取当前星期几?

Posted

技术标签:

【中文标题】如何使用 date.h 在 C++ 中获取当前星期几?【英文标题】:How do I get the current day of week in C++ using date.h? 【发布时间】:2019-08-20 08:49:56 【问题描述】:

我正在使用 C++ 14 并试图获取当前星期几。经过一番阅读,我正在使用 Howard E. Hinnant 的 date.h。

但是我很难获得一周中的某一天(编码为 0 到 6)。

这样的东西会打印出Thu:

 int main(void)
 
     date::sys_days t;
     weekday wdt;
     cout << wd << '\n';
 

本网站上关于获取星期几的许多答案都使用chrono

如何使用date.h 根据程序运行的时间将当前工作日打印为 0-6 的范围?

例如,如果我今天(星期二)运行该程序,我期望值为 2。

任何建议将不胜感激。


只是为了清楚我想要实现的目标,在 Java 中类似:

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/London"));
int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);

【问题讨论】:

您列出的程序有什么问题? @einpoklum 我展示的程序总是打印出Thu。我希望能够打印出星期几 【参考方案1】:

您的代码的问题是t 没有被初始化为任何有趣的东西。您只需将其设置为“现在”。不过有一个小问题:now() 返回不同类型的时间点,它不能自动转换为 date::sys_days 值。

所以,以下是使您的程序正常工作的最小更改:

#include "date.h"
#include <iostream>
#include <cstdint>
   
int main()

     auto now = std::chrono::system_clock::now();
     date::sys_days t  std::chrono::time_point_cast<date::days>(now) ;
     date::weekday wdt;
     std::cout << wd << '\n';

编辑:现在让我们做更多的事情,感谢@HowardHinnant 提供的信息丰富的 cmets。

使用更有意义的名称

main() 的代码替换为

auto now = std::chrono::system_clock::now();
date::sys_days now_in_days  std::chrono::time_point_cast<date::days>(now) ;
date::weekday weekday now_in_days;
std::cout << weekday << '\n';

以数字形式获取工作日

你说你想把工作日作为一个数字。好吧,我们可以这样做:

auto weekday_index = weekday.c_encoding();

类型为unsigned,值在0...6范围内

获取您自己时区的工作日

到目前为止,您和我的代码都是 UTC。默认情况下这很好,但可能会给你一些令人惊讶的工作日。我们可以使用zoned_time 并写:

auto now = std::chrono::system_clock::now();
auto now_local = zoned_timecurrent_zone(), now.get_local_time();
date::sys_days now_local_in_days  std::chrono::time_point_cast<date::days>(now_local) ;
date::weekday weekday now_local_in_days;
auto weekday_index = weekday.c_encoding();

了解纪元 (1970) 之前的日期

这非常烦人,但time_point_cast() 可能并不总是如你所愿!霍华德说,在 1970 年之前的几天里,我们需要改用 floor()

date::sys_days now_local_in_days  std::chrono::floor<date::days>(now_local) ;

最终程序

#include "date.h"
#include <iostream>
#include <cstdint>
   
int main()

    auto now = std::chrono::system_clock::now();
    auto now_local = zoned_timecurrent_zone(), now.get_local_time();
    date::sys_days now_local_in_days  std::chrono::floor<date::days>(now_local) ;
    date::weekday weekday now_local_in_days;
    auto weekday_index = weekday.c_encoding();
    std::cout << weekday_index << '\n';

如果今天是星期二,结果输出应该是2

【讨论】:

更多信息和注意事项:1) 您可以使用wd.c_encoding()weekday wd 转换为[0, 6] 范围内的unsigned。 2) 上述公式以 UTC 格式返回当前的weekday。要获取本地时间的当前weekday,请将nowzoned_timecurrent_zone(), now.get_local_time() 转换为local_time,然后然后 截断为days 精度并转换为weekday。 3)time_point_cast 将为您提供 1970 年之后的所有时间的正确答案。为确保所有时间点的答案正确,请使用floor&lt;days&gt; 而不是time_point_cast&lt;days&gt; @HowardHinnant:你想把它编辑成答案,还是我应该? 欢迎您编辑它。我的 cmets 只是为了提供信息。请随意使用它们。无论如何,我都赞成你的回答。 :-) 感谢@HowardHinnant 提供的信息丰富的评论和date.h 的总体情况! @Azmisov:看起来它从中间的某个地方滑落了。你介意再看看吗?【参考方案2】:

这将使用 date.h 给出当天的索引:

using namespace date;
using namespace std::chrono;
auto now = system_clock::now();
std::cout << "The current time is " << now << " UTC\n";
auto current_day = (year_month_weekdayfloor<days>(now).weekday() - Sunday).count();
std::cout << "current_day " << current_day << "\n";

你也可以使用std::time_get::get_weekday

#include <iostream>       // std::cout, std::ios
#include <sstream>        // std::istringstream
#include <ctime>          // std::tm
#include <locale>         // std::locale, std::time_get, std::use_facet

int main ()

  std::locale loc;        // classic "C" locale

  // get time_get facet:
  const std::time_get<char>& tmget = std::use_facet <std::time_get<char> > (loc);

  std::ios::iostate state;
  std::istringstream iss ("Friday");
  std::tm when;

  tmget.get_weekday (iss, std::time_get<char>::iter_type(), iss, state, &when);

  std::cout << "weekday: " << when.tm_wday << '\n';
  return 0;

或:

time_t t = time(nullptr);
tm* timePtr = localtime(&t);
uint32_t y = timePtr->tm_year + 1900;
uint32_t m = timePtr->tm_mon + 1;
uint32_t d = timePtr->tm_wday;
cout<< d<<endl;

【讨论】:

这可行,但会根据硬编码的std::istringstream iss ("Friday"); 打印出星期几。我如何在没有自己硬编码的情况下实现类似的输出?我希望能够根据程序运行的时间返回一个数字 0-6。 是的,这按预期工作。但是,我最初的问题需要使用date.h,因为我找不到如何在这个库中正确实现。

以上是关于如何使用 date.h 在 C++ 中获取当前星期几?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 psql 中获取当前月份星期日的计数?

如何从 C++ 中的 tm 对象获取星期几?

如何在visual studio中获取当前的星期几

如何在python中获取当前月份的最后一个星期三?

以小时和分钟获取当前时间

如何在 Angular 8 或 javascript 中明智地获取当前日期每周日