繁体   English   中英

在 C++ 中获取当前年份的更优雅的方式

[英]More elegant way to get the current year in C++

我对 C++ 很陌生。我需要获取当前年份并将其存储在一个 int 中。

我来到这个解决方案:

std::time_t result = std::time(nullptr);
std::istringstream iss(ctime(&result));

iss.ignore(20);
int year;
iss >> year;

我发现这个解决方案有点难看,即使它有效,因为它看起来不是很健壮,而且需要很多步骤才能完成。

会有更好的方法吗?

简而言之,以下get_this_year() function 应该以 C++20 的方式为您工作。

它将为您返回当年的int

// year.cpp

#include <chrono>
#include <iostream>

int get_current_year() {
  using namespace std::chrono;
  return static_cast<int>(
      year_month_day{time_point_cast<days>(system_clock::now())}.year());
}

int main() {
  int year = get_current_year();
  std::cout << year << std::endl; // 2022
}

这应该用例如g++ -std=c++20 year.cpp


但我也想以详细的方式扩展它,解释每一步发生的事情。

// year.cpp

#include <chrono>
#include <iostream>

int get_current_year() {
  using namespace std::chrono;
  auto now = system_clock::now();           // 1. get time_point for now
  auto today = time_point_cast<days>(now);  // 2. cast to time_point for today
  auto ymd = year_month_day(today);         // 3. convert to year_month_day 
  auto year = ymd.year();                   // 4. get year from year_month_day
  return static_cast<int>(year);            // 5. an explicit cast is required 
}

int main() {
  int year = get_current_year();
  std::cout << year << std::endl; // 2022
}

现在,更详细地,明确拼出所有类型 -

// year.cpp

#include <chrono>
#include <iostream>

int get_current_year() {
  std::chrono::time_point<std::chrono::system_clock,
                          std::chrono::system_clock::duration>
      now = std::chrono::system_clock::now();
  std::chrono::time_point<std::chrono::system_clock, std::chrono::days> today =
      std::chrono::time_point_cast<std::chrono::days>(now);
  std::chrono::year_month_day ymd = std::chrono::year_month_day(today);
  std::chrono::year year = ymd.year();
  return static_cast<int>(year);
}

int main() {
  int year = get_current_year();
  std::cout << year << std::endl; // 2022
}

基本上有两种类型的格式来表示时间点:

  1. 基于序列 - 例如,这个时间点是自纪元以来的x秒(例如 1970 年 1 月 1 日)
  2. 基于字段——例如这个时间点是year/month/day

从系统时钟我们得到一个基于序列的时间点。 我们需要将其转换为基于字段的时间点。 然后从这个基于字段的时间点我们提取年份。

C++20,你可以使用std::chrono来达到这个目的。

P0355R7 扩展到日历和时区

之后通过字符串解析将time_t转换为字符串在我看来是不必要的复杂且容易出错。 正如@Ted 的评论中已经抱怨的那样,这可能会引入文本 output 的本地化,这可能会使解析变得不可靠。

std::time()一起,有可用的

  • std::localtime()

    将自纪元以来的给定时间作为 std::time_t 值转换为日历时间,以本地时间表示。

  • std::gmtime()

    将自纪元以来的给定时间作为 std::time_t 值转换为日历时间,以协调世界时 (UTC) 表示。

两者都返回一个指向struct tm的指针,其中包含一个公共成员

int tm_year自 1900 年以来的年数

一个小样本:

#include <ctime>
#include <iostream>

int main()
{
  std::time_t t = std::time(nullptr);
  std::tm *const pTInfo = std::localtime(&t);
  std::cout << "Current year: " << 1900 + pTInfo->tm_year << '\n';
}

Output:

Current year: 2019

coliru 现场演示

#include <ctime>
#include <iostream>
using namespace std;

int main()
{
time_t current_time;

current_time = time(NULL);
int a;
a = 1970 + current_time / 31537970; 
cout << a << " is the current year.";

return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM