I am working on a utility function to get the current date and time. My objective is to do this in a generic and portable way. I would like to stay way from platform specific code to allow the functionally of this method to be portable.
I had originally asked a question over at Stack Overflow followed up by another question.
The question(s) that I had asked in the former Stack Overflow Q/A is more relevant that the first in regards to this question or set of questions.
Here is the code that I had written to get the current date and time:
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 <ctime>
#include <exception>
#include <iomanip>
#include <iostream>
using namespace util;
int main() {
try {
std::stringstream stream1;
currentDateAndTime(stream1, TimeLocale::GMT);
std::cout << stream1.str() << '\n';
std::stringstream stream2;
currentDateAndTime(stream2, TimeLocale::LOCAL);
std::cout << stream2.str() << '\n';
std::stringstream stream3;
currentDateAndTime(stream3, TimeLocale::BOTH);
std::cout << stream3.str() << '\n';
std::stringstream stream4;
currentDateAndTime(stream4, TimeLocale::GMT | TimeLocale::LOCAL);
std::cout << stream4.str() << '\n';
} catch ( const std::exception& e ) {
std::cout << "Exception Thrown: " << e.what() << std::endl;
return EXIT_FAILURE;
} catch (...) {
std::cout << __FUNCTION__ << " Caught Unknown Exception" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
And the above code would generate a nicely formatted possible result:
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
Currently as it stands, this is acceptable for me considering my current situation. I'm not quite able to use the new features that can be found in <std::chrono>
for its calendar
resources, as I'm stuck with Visual Studio 2017 and C++17.
There are a few things that I would like to know about the above function and its functionality.
- Other than using library functions that have been marked deprecated such as
std::gmtime
andstd::localtime
and having to suppress the compiler warning, is the overall above code considered good design, and is it considered readable and reliable? - Is there anything that could be done to improve this: Are there any corner case errors that I may have missed, can this be made more efficient.
- Would this above code be considered portable, cross-platform?
The last thing I would like to know are there any other standard ways to achieve this through the standard library without using platform specific code?
I wouldn't mind using chrono
but its newer features are not quite yet available; and I don't want to use any third party libraries like boost
for example.
I am aware of the fact that different operating systems as well as different hardware (processors) retrieve and calculate the current time differently, and that different regions have different types of calendars and time zone formats.
Above are some of the reasons that made it a formidable challenge to retrieve the current date and time using only standard C++. I might just have to wait for the release of Visual Studio 2019 for C++20 to arrive.
I'm looking forward to any and all feedback.
<ctime>
functions? I don't think there's any proposal to remove them in the C++20 timeframe, or even beyond. \$\endgroup\$c++ latest draft standard
which should be C++17; if I remove the#pragma warning(push) #pragma warning(disable : 4996) #pragma warning(pop)
away from thecurrentDateAndTime(...)
function my compiler yells at me thatstd::gmtime
andstd::localtime
are not considered safe and that they have been marked for deprecation. \$\endgroup\$std::chrono
calendar
features that will be added to the standard come C++20 in Visual Studio 2019 and or other compilers that will support C++20 when it is officially released. \$\endgroup\$gmtime_r()
and the like, or their platform's equivalent. But if you're writing a single-threaded program, there's no need to panic! \$\endgroup\$