3
string GetTime() { time_t Timev; struct tm * TimeInformation; time(&(time_t)Timev); (tm*)TimeInformation = localtime(&(time_t)Timev); char Timec[100]; strftime((char*)Timec, 100, "[%X]:", (tm*)TimeInformation); string GetTimex((char*)Timec); return GetTimex; }; 

Why do I get the warning

warning C4996: 'localtime': This function or variable may be unsafe. Consider using localtime_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.

Is there any other way to get time in format [Hour:Minutes:Second], and is it possible to shorten the code like int abc; abc=123 to int abc{123}?

6
  • C-style casts are not recommended in C++. Every one of those six should be superfluous. The localtime() function is not thread-safe; it returns a pointer to static data. Using localtime_s() as the error suggests avoids that problem; you provide the storage for the result. You could use time_t Timev = time(0); struct tm *TimeInformation = localtime(&Timev); and you should be able to avoid the named string variable too. Commented Mar 22, 2017 at 15:29
  • Why the crazy cast of Timev from time_t to time_t and of Timec from char[] to char*? That really makes your code hard to read! Also, there's no GetTimex() in any standard library header, so you might want to explain what that is. Commented Mar 22, 2017 at 15:46
  • @TobySpeight GetTimex is a badly-named std::string with a weird initialization syntax. Commented Mar 22, 2017 at 16:32
  • Thanks, @Quentin - I think I was thrown by the Get... at the front of the name! return Timec; would have been much clearer. Commented Mar 22, 2017 at 16:40
  • @TobySpeight Thanks, from what you said "time_t to time_t" i just wanted to specific the type of the variable ... is it wrong ? i learning C++ myself dont know much about it ... && sry for any trouble =3 Commented Mar 25, 2017 at 11:40

4 Answers 4

4

If you are willing to install Howard Hinnant's free, open-source tz library, then GetTime() can be simplified down to:

#include "tz.h" #include <string> std::string GetTime() { using namespace std::chrono; using namespace date; return format("[%X]:", make_zoned(current_zone(), system_clock::now())); } 

This just output for me:

[10:42:32]: 

Here are the installation directions (including for Windows).

Sign up to request clarification or add additional context in comments.

2 Comments

Just realised that my edit makes it look like you refer to yourself in the third person - sorry about that; I just wanted to ease the recognition for anyone who's already using (or avoiding) your library. P.S. is there an RFP for Debian, so it's more easily (and safely) usable?
@TobySpeight: Not a problem. I reviewed your edit, and I'm fine with it, thanks. I've used the same formulation myself. Someone mentioned to me that they were working on a Debian package, but I don't know the status of it.
2

You could use this example:

#include <iostream> #include <iomanip> // std::put_time #include <ctime> // std::localtime, std::time, std::time_t, std::gmtime int main() { std::time_t t = std::time(nullptr); std::cout << "UTC: " << std::put_time(std::gmtime(&t), "%X") << '\n'; std::cout << "local: " << std::put_time(std::localtime(&t), "%X") << '\n'; } 

Possible output:

UTC: 14:18:02 local: 14:18:02 

And your GetTime would then be:

std::string GetTime() { std::time_t t = std::time(nullptr); std::stringstream ss; ss << std::put_time(std::localtime(&t), "[%X]"); return ss.str(); } 

1 Comment

You could use that code, but it doesn't address the underlying issue that std::localtime() returns static storage that may be modified by other threads concurrently.
1

localtime has an internal storage that is static, which means it is not threadsafe. Most systems do have threadsafe alternatives, but they are not part of the standard library. For example, Windows has localtime_s and Linux/Posix has localtime_r. The std library functions std::strftime and std::put_time could be a safer alternative, like explained in this article

Comments

1

The return value of std::localtime() (when it suceeds) is a

pointer to a static internal std::tm object

Further,

The structure may be shared between std::gmtime, std::localtime, and std::ctime, and may be overwritten on each invocation.

(from cppreference)

This means that if you're using any of these functions in other threads, you may have a data race. If you're sure that no other threads are using any of those functions (perhaps because your program is single-threaded), then you may safely ignore the warning.

It appears that your compiler is recommending you use its implementation-defined alternative - whether you do is up to you, but you might want to consider isolating any platform-dependency you then introduce.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.