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

enxuqcxy  于 2022-12-15  发布在  其他
关注(0)|答案(4)|浏览(273)

我对C++还是个新手。我需要得到当前年份并将其存储在一个int型变量中。
我得出了这个解决方案:

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

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

我发现这个解决方案有点难看,即使它工作,因为它似乎不是很健壮,它需要很多步骤来做不太多。
有没有更好的办法?

643ylb08

643ylb081#

C++20中,您可以使用std::chrono来实现此目的。
P0355R7 Extending to Calendars and Time Zones

#include <iostream>
#include <format>
#include <chrono>
int main()
{
    const auto now = std::chrono::system_clock::now();
    std::cout << std::format("{:%Y}", now); // => 2021
}
o0lyfsai

o0lyfsai2#

在我看来,将time_t转换为字符串并随后进行字符串解析是不必要的复杂和容易出错的。正如@Ted的评论中所抱怨的那样,这可能会引入文本输出的本地化,从而使解析变得不健壮。
std::time()一起,还有

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

将自纪元std::time_t值起的给定时间转换为日历时间,以协调世界时(UTC)表示。
两者都返回指向struct tm的指针,struct tm包含公共成员
自1900年以来int tm_year
小样本:

#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';
}

输出:

Current year: 2019

Live Demo on coliru

56lgkhnf

56lgkhnf3#

#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;
}
wd2eg0qa

wd2eg0qa4#

简而言之,下面的get_this_year()函数应该可以用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.基于序列-例如,该时间点自一个时期(例如,1970年1月1日)以来为x
1.基于字段-例如,该时间点为year/month/day
从系统时钟中我们得到一个基于序列的时间点,我们需要将它转换成一个基于字段的时间点,然后从这个基于字段的时间点中提取年份。

相关问题