将时间戳打印到流的最简单方法

Easiest way to print timestamp to ostream

本文关键字:最简单 方法 时间戳 打印      更新时间:2023-10-16

我想为std::cout/std::cerr ostreams的某些输出添加一个时间戳,而不使用修改后的标准流,如下所示:

std::cerr << timestamp << "Warning!n";

左右:

std::cerr << timestamp() << "Warning!n";

输出应如下所示:

[2020-01-23 17:40:15 CET] Warning!

但我真的对我想出的东西不满意:

class TimeStamp {};
std::ostream &operator<<(std::ostream &stream, const TimeStamp &ts) 
{
std::time_t t = std::time(nullptr);
stream << "[" << std::put_time(std::localtime(&t), "%F %T %Z") << "] ";
return stream;
}
TimeStamp ts;
int main()
{
std::cerr << ts << "Warning!n";
std::cerr << ts << "Another warning!n";
}

所以我基本上定义了一个空类,使用全局声明并重载"<<"运算符。这感觉不对。像 timestamp(( 这样的静态函数可能更适合,但我不太确定如何继续。我在网上找到的所有示例都使用了重载的"<<"运算符,但这样做通常更有意义,因为输出了一些类状态。我可以在本地创建一个 ostream 并在函数中返回它吗?

你这样做的方式没有错。但是如果你正在寻找替代方案,你可以创建一个ostream包装器:

class Logger {
private:
std::ostream &stream;
void print_time() {
std::time_t t = std::time(nullptr);
stream << "[" << std::put_time(std::localtime(&t), "%F %T %Z") << "] ";
}
public:
//Maybe also take options for how to log?
Logger(std::ostream &stream) : stream(stream) { }
template <typename T>
std::ostream &operator<<(const T &thing)  {
print_time();
return stream << thing;
}
};
int main()
{
Logger log(std::cerr);
log << "Warning!" << std::endl;
log << "Another warning!" << std::endl;
}

在这里看到它运行:https://ideone.com/YRawuQ

如果您只是在寻找一个独立的函数,这是我从"像 timestamp(( 这样的静态函数"中理解的,您可以将日期作为字符串返回:

std::string timeStamp(){
std::ostringstream strStream;
std::time_t t = std::time(nullptr);
strStream<< "[" << std::put_time(std::localtime(&t), "%F %T %Z") << "] ";
return strStream.str();
}

int main(){
std::cout<<timeStamp()<<" Testing!";   
return 0;
}

请记住包含流

您可以使用日期和时间库中的标准std::chrono::time_point类来表示时间戳。然后,您需要将该时间戳转换为std::time_t类型,并最终根据格式字符串将给定日历时间的日期和时间信息转换为字符串。

auto const now = std::chrono::system_clock::now();
auto now_time = std::chrono::system_clock::to_time_t(now);
std::cout << std::put_time(std::localtime(&now_time), "%F %T") << std::endl;

对于那些想知道更多...

可以使用表示有关源代码的某些信息(如文件名、行号和函数名称(的source_location类。它正在合并到 ISO C++ 中并可供使用。

完整代码

#include <ctime>
#include <chrono>
#include <iomanip>
#include <iostream>
#include <string_view>
#include <experimental/source_location>
void error(std::string_view const& message,
std::ostream& os = std::cout,
std::experimental::source_location const& location = std::experimental::source_location::current()) {
auto const now = std::chrono::system_clock::now();
auto now_time = std::chrono::system_clock::to_time_t(now);
os << "[" << std::put_time(std::localtime(&now_time), "%F %T") << "] "
<< "[INFO] "
<< location.file_name() << ":"
<< location.line() << " "
<< message << 'n';
}
void info(std::string_view const& message,
std::ostream& os = std::cout,
std::experimental::source_location const& location = std::experimental::source_location::current()) {
auto const now = std::chrono::system_clock::now();
auto now_time = std::chrono::system_clock::to_time_t(now);
os << "[" << std::put_time(std::localtime(&now_time), "%F %T") << "] "
<< "[INFO] "
<< location.file_name() << ":"
<< location.line() << " "
<< message << 'n';
}
int main() {
error("Some error");
info("Some info");
// or
error("Some error 2", std::cerr);
info("Some info 2", std::cerr);
return 0;
}

现场查看