1

I am building an application in C++ in which I need Time objects to give access to the current system time. To do this, I use time.h. My two constructors go as follow:

Time::Time(bool p_daylightSavingEnabled /* = true */)
{
    time_t rawTime = time(nullptr);
    struct tm* timeInfo = localtime(&rawTime);

    timeInfo->tm_isdst = static_cast<int>(p_daylightSavingEnabled);

    m_hours   = timeInfo->tm_hour;
    m_minutes = timeInfo->tm_min;
    m_seconds = timeInfo->tm_sec;
}

Everything is pretty straight forward except for the use of the tm_isdst flag which I added because a unit test fails when the hour changes, but still is mysterious to me. I have found no clear documentation on how to properly use this flag on the Internet and I have heard that on some systems, it is not even available (i.e. set to 0).

Is this a correct way to use tm_isdst and if not, how should it be used (for example in such a constructor) to work properly across different systems?

Clarification: For now, I am not interested in any alternatives of time.h.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
BobMorane
  • 3,870
  • 3
  • 20
  • 42
  • 1
    No; you should look at what `localtime` returns; you shouldn't pretend that it can be ignored/overridden without more compensatory changes. And yes, it is ill-defined, in general. – Jonathan Leffler Sep 16 '17 at 22:22
  • @JonathanLeffler *you shouldn't pretend that it can be ignored/overridden without more compensatory changes.* What do you mean by more compensatory changes? Do you have an example I could look at? – BobMorane Sep 16 '17 at 22:30
  • The manual page for `localtime` fully explains what `is_dst` means. If there's something unclear about the description of that field in the `localtime` manual page, you should explain what exactly is unclear to you. – Sam Varshavchik Sep 16 '17 at 22:33
  • The "No" is easy. The explanation isn't. You'll need to explore what the systems you use actually do — using a variable to set `rawTime` rather than `time()`. I'll poke around my collection of code and see whether I can demonstrate my concerns in an MCVE-sized example. – Jonathan Leffler Sep 16 '17 at 22:33
  • You can't just change a value in the structure and expect other values to change as a result of that, without perhaps calling another function to do so for you. But in this case, the members of the struct are informational; they are for you to read, not to write. – phonetagger Sep 16 '17 at 22:37
  • Don't spam tags. That's not C. – too honest for this site Sep 16 '17 at 22:39

1 Answers1

0

Your code should be simply:

Time::Time()
{
    time_t rawTime = time(nullptr);
    struct tm* timeInfo = localtime(&rawTime);

    m_hours   = timeInfo->tm_hour;
    m_minutes = timeInfo->tm_min;
    m_seconds = timeInfo->tm_sec;
}

Finding out what time it is "now" does not require you to tell the machine whether DST is on or off. It already knows.

P.S.: Your code is thread-unsafe for no reason--use localtime_r() instead to fix this.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • @johnswinck If I understand you correctly, if I do not deal with the DST flag and that my system supports daylight saving times, it should know by itself when to change the time (and change it)? In other words, the DST flag, when read, is only there to tell the programmer if the system supports daylight saving time? – BobMorane Sep 16 '17 at 22:58
  • 1
    The DST flag is ONLY there to inform you whether the system is currently on DST or not. The system knows by itself when to change time for DST. – John Zwinck Sep 16 '17 at 23:00