如何将C++中ctime()转换为指定格式的日期字符串?
回答
不行,ctime()完全没办法实现自定义时间格式——它的输出格式是固定死的,就是你现在看到的Sun Sep 29 02:41:40 2019这种样式,没有任何参数能让你调整它的输出结构。
不过你可以用这两种更灵活的方法来实现你想要的格式:
方法1:用C标准库的strftime()(适合新手快速上手)
strftime()是专门用来格式化时间字符串的函数,支持自定义格式串,刚好符合你的需求。修改后的代码大概是这样:
#include <ctime> // 要包含这个头文件 // ... 你的原有代码 ... tempstring = "Your last login was: "; time_t lastLogin = player->getLastLoginSaved(); char timeBuffer[100]; // 定义一个足够大的缓冲区存格式化后的字符串 tm timeDetails; // 注意:Windows下用localtime_s,Linux/macOS下用localtime_r(更线程安全) // 如果只是测试,也可以用localtime,但要注意它不是线程安全的 #ifdef _WIN32 localtime_s(&timeDetails, &lastLogin); #else localtime_r(&lastLogin, &timeDetails); #endif // 用你指定的格式串生成时间字符串 strftime(timeBuffer, sizeof(timeBuffer), "%d. %b %Y %H:%M:%S CET", &timeDetails); tempstring += timeBuffer; tempstring += "."; // 如果你需要末尾的句号的话 AddTextMessage(msg, MSG_STATUS_DEFAULT, tempstring.c_str());
简单解释下关键部分:
localtime_s/localtime_r:把Unix时间戳(time_t)转换成包含年、月、日等细节的tm结构体strftime:按照你给的%d. %b %Y %H:%M:%S CET格式,把tm结构体的内容转换成字符串%d:两位数字的日期(比如29)%b:缩写的月份名称(比如Sep)%Y:四位数字的年份(比如2019)%H:%M:%S:24小时制的时:分:秒
方法2:用C11及以后的现代标准库(更符合C风格)
如果你用的是C++11或更新的版本,可以用<chrono>和<iomanip>库来实现,不用手动管理字符缓冲区,代码更安全:
#include <chrono> #include <iomanip> #include <sstream> // 要包含这个头文件 // ... 你的原有代码 ... tempstring = "Your last login was: "; time_t lastLogin = player->getLastLoginSaved(); // 把time_t转换成C++的时间点,然后格式化 std::ostringstream timeStream; timeStream << std::put_time(std::localtime(&lastLogin), "%d. %b %Y %H:%M:%S CET"); tempstring += timeStream.str(); tempstring += "."; AddTextMessage(msg, MSG_STATUS_DEFAULT, tempstring.c_str());
这里std::put_time就是C++标准库提供的格式化时间的工具,用法和strftime类似,格式串是完全一样的。
关于时区的小提醒
上面的代码默认会使用系统当前的时区,如果你的系统时区不是CET,输出的时间会是系统时区的时间。如果要强制输出CET时间,可以在调用时间函数前设置时区环境变量:
#ifdef _WIN32 _putenv_s("TZ", "CET-1CEST,M3.5.0,M10.5.0/3"); #else setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 1); #endif tzset(); // 刷新时区设置
这样后续的localtime系列函数就会用CET时区来解析时间了。
内容的提问来源于stack exchange,提问作者rick astley




