I am writing a simple logging class in C++ for learning purposes. My code contains a function that returns a string of today's date. However, I get a compiler error whenever 'localtime' is called.
std::string get_date_string(time_t *time) {
struct tm *now = localtime(time);
std::string date = std::to_string(now->tm_mday) + std::to_string(now->tm_mon) + std::to_string(now->tm_year);
return date;
}
I have tried using #define _CRT_SECURE_NO_WARNINGS
. It didn't work and the same error appeared. I also tried putting _CRT_SECURE_NO_WARNINGS
inside the preprocessor definitions in the project properties. This gave an unresolved external error.
Does anyone have any ideas on what to do?
localtime can be dangerous to use because it returns a pointer to a memory area which it owns, so if you call it multiple times you need to make sure each time you copy the struct. Also, by the way, the way you create a string, if you get "2112016" you don't know if that's 21/1/2016 or 2/11/2016.
The localtime() function takes a pointer of type time_t as its argument and returns a pointer object of structure tm . The value returned by localtime() function is the local time. Then, the hours, minutes and seconds can be accessed using tm_hour , tm_min and tm_sec respectively.
ctime returns a pointer to static data and is not thread-safe. In addition, it modifies the static tm object which may be shared with gmtime and localtime.
The problem is that std::localtime
is not thread-safe because it uses a static buffer (shared between threads). Both POSIX
and Windows
have safe alternatives: localtime_r and localtime_s.
Here is what I do:
inline std::tm localtime_xp(std::time_t timer)
{
std::tm bt {};
#if defined(__unix__)
localtime_r(&timer, &bt);
#elif defined(_MSC_VER)
localtime_s(&bt, &timer);
#else
static std::mutex mtx;
std::lock_guard<std::mutex> lock(mtx);
bt = *std::localtime(&timer);
#endif
return bt;
}
// default = "YYYY-MM-DD HH:MM:SS"
inline std::string time_stamp(const std::string& fmt = "%F %T")
{
auto bt = localtime_xp(std::time(0));
char buf[64];
return {buf, std::strftime(buf, sizeof(buf), fmt.c_str(), &bt)};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With