我知道可能曾经有人问过这个问题,但这是我先前发现的here问题之一的跟进。使其他问题与众不同的原因在于,我正在寻找与我的编译器相关的最新信息:使用C ++ 17的Visual Studio 2017-最新草案标准。
我知道随着时间的推移,C ++ 20将发布并在我期待的Visual Studio 2019中可用。但是目前;我仍在Windows 7上使用Visual Studio 2017,并且当前绑定到C ++ 17。我发现这个Q/A与提供了很好答案的类似,但是当我开始使用<ctime>
或<time.h>
函数时,例如:
std::gmtime()
std::localtime()
我的编译器对我大喊:这些功能被标记为不安全且已弃用。我正在尝试编写如下函数:
-DateAndTime.h-
#pragma once
#include <ctime>
#include <iomanip>
#include <iostream>
#include <sstream>
namespace util {
enum class TimeLocale {
LOCAL = 0x01,
GMT = 0x02,
BOTH = (LOCAL | GMT)
};
inline TimeLocale operator|(TimeLocale a, TimeLocale b) {
return static_cast<TimeLocale>(static_cast<int>(a) | static_cast<int>(b));
}
#pragma warning( push )
#pragma warning( disable : 4996 )
inline void currentDateAndTime(std::stringstream& stream, TimeLocale locale) {
std::time_t t = std::time(nullptr);
if (locale == TimeLocale::GMT) {
stream << "UTC: " << std::put_time( std::gmtime(&t), "%c, %Z") << '\n';
}
if (locale == TimeLocale::LOCAL) {
stream << "LOCAL: " << std::put_time(std::localtime(&t), "%c, %Z") << '\n';
}
if (locale == TimeLocale::BOTH) {
stream << "UTC: " << std::put_time(std::gmtime(&t), "%c, %Z") << '\n'
<< "LOCAL: " << std::put_time(std::localtime(&t), "%c, %Z") << '\n';
}
}
#pragma warning( pop )
} // namespace util
-main.cpp-
#include "DateAndTime.h"
#include <iostream>
#include <sstream>
using namespace util;
int main() {
try {
std::stringstream stream1;
getCurrentTime(stream1, TimeLocale::GMT);
std::cout << stream1.str() << '\n';
std::stringstream stream2;
getCurrentTime(stream2, TimeLocale::LOCAL);
std::cout << stream2.str() << '\n';
std::stringstream stream3;
getCurrentTime(stream3, TimeLocale::BOTH);
std::cout << stream3.str() << '\n';
std::stringstream stream4;
getCurrentTime(stream4, TimeLocale::GMT | TimeLocale::LOCAL);
std::cout << stream4.str() << '\n';
// ExceptionHandler is one of my class's and can be ignored in this context
// You can replace this with std::exception, std::cerr, etc...
} catch ( ExceptionHandler& e ) {
std::cout << "Exception Thrown: " << e.getMessage() << std::endl;
return EXIT_FAILURE;
} catch (...) {
std::cout << __FUNCTION__ << " Caught Unknown Exception" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
如果我使用#pragma warning( disable : 4996 )
我得到的输出像这样:
UTC: 02/20/19 05:44:38, Eastern Standard Time
Local: 02/20/19 00:44:38, Eastern Standard Time
UTC: 02/20/19 05:44:38, Eastern Standard Time
Local: 02/20/19 00:44:38, Eastern Standard Time
UTC: 02/20/19 05:44:38, Eastern Standard Time
Local: 02/20/19 00:44:38, Eastern Standard Time
哪个看起来很棒。但是,我希望不要使用任何已标记为不赞成使用的功能,这些功能不是特定于平台的,这些功能通常是C ++ 17当前可用的通用,可移植和跨平台的。最好是来自标准库的东西。我既不想使用第三方库,也不想提高效率。 std::chrono
是一个不错的选择,但是它们的calendar
部分要等到C ++ 20的完整版本才可用。我剩下什么样的选择?
答案 0 :(得分:1)
不建议使用gmtime和localtime函数。
仅对Visual Studio弃用了它们,因为Visual Studio提供了替代的gmtime_s和localtime_s,因此我将使用这些功能。 在Unix下,如果您想保持线程安全,则可以使用gmtime_r和localtime_r。另请参见this answer
在Windows下编写一个内联gmtime_r和localtime_r并调用gmtime_s和localtime_s,您将拥有几乎标准的跨平台解决方案,直到C ++ 20。