以更优雅的方式获得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;
我发现这个解决方案有点丑陋,即使它有效,因为它看起来不是很强大,而且需要很多步骤才能做很多事情。
有没有更好的方法
?C++20,您可以使用std::chrono
来实现此目的。
P0355R7扩展到日历和时区
#include <iostream>
#include <format>
#include <chrono>
int main()
{
const auto now = std::chrono::system_clock::now();
std::cout << std::format("{:%Y}", now); // => 2021
}
在我看来,通过字符串解析将time_t
转换为字符串似乎不必要的复杂且容易出错。正如@Ted的评论中所抱怨的那样,这可能会引入文本输出的本地化,这可能会使解析不可靠。
连同std::time()
,有可用的
std::localtime()
将自纪元以来的给定时间(作为 std::time_t 值(转换为以本地时间表示的日历时间。
std::gmtime()
将自纪元以来的给定时间作为 std::time_t 值转换为日历时间,以协调世界时 (UTC( 表示。
两者都返回指向包含公共成员的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
科里鲁的现场演示
#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;
}
简而言之,以下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
}
基本上有两种类型的格式来表示时间点:
- 基于序列 - 例如,此时间点是自纪元以来的
x
秒(例如 1970 年 1 月 1 日( - 基于字段 - 例如,此时间点是
year/month/day
从系统时钟中,我们得到一个基于串行的时间点。我们需要将其转换为基于字段的时间点。然后从这个基于字段的时间点中提取年份。
这里有一个简单的方法:
string timestamp_str = __TIMESTAMP__;
auto timestamp_tokens = split(timestamp_str, ' ');
std::cout << timestamp_tokens[timestamp_tokens.size() - 1] << std::endl;
split((函数通过分隔符"空格"拆分字符串。您可以编写一个自定义方法来获取最后一个令牌(最后一个令牌是年份(。你可以从这个链接获取split((的实现。下面是一个示例实现:
vector<string> split(string string_with_delim, char delim)
{
auto i = 0;
vector<string> result;
auto pos = string_with_delim.find(delim);
while(pos != string::npos)
{
string res = string_with_delim.substr(i, pos-i);
result.push_back(res);
i = ++pos;
pos = string_with_delim.find(delim, pos);
}
result.push_back(string_with_delim.substr(i, string_with_delim.size()));
return result;
}
- 如何在c++中为模板函数实例创建快捷方式
- 在c代码之间共享数据的最佳方式
- 在C++中将函数压缩为两种方式
- 以螺旋方式打印矩阵的程序.(工作不好)
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- 创建引用向量的优雅方式
- Constexpr替代了新的放置方式,可以让内存中的对象保持未初始化状态
- 获取用C/C++打印的最后一个字符串
- 使用QQuickFramebufferObject时同步数据的最佳方式是什么
- 不同/较旧的处理器运行c++代码的方式是否不同
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 重载方法的方式会在使用临时调用时生成编译器错误
- 在reactor中存储eventHandlers的最佳方式是什么
- 如何以优化的方式同时迭代两个间距不相等的数组
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 为什么C++有不同的变量初始化方式?
- 在AVX通道中混洗的最佳方式
- 如何重新定义MPI_FLOAT,MPI_DOUBLE以 typedef 的方式
- 如何以静态代码分析友好的方式使用 #define 防护?