Question

I know, this particular kind of thing has been answered a number of times, but I think, my question here is more to do with general C++ stuff than ctime() or date/time conversion. I just happened to try it out with this. So, here is the code:

#include <iostream>
#include <ctime>

using std::cout;
using std::endl;
using std::string;

void strTime( int iM, int iD, int iY )
{
    time_t rwTime;
    time( &rwTime );            // current epoch time

    // 1st set:: using tmInfo_11
    struct tm *tmInfo_11; 
    tmInfo_11 = localtime( &rwTime );
    tmInfo_11->tm_mon = iM - 1;
    tmInfo_11->tm_mday = iD; 
    tmInfo_11->tm_year = iY - 1900;
    mktime( tmInfo_11 );
    cout << "tmInfo_11 RESULt: " << tmInfo_11->tm_wday << endl;

    // 2nd set:: using tmInfo_22 //
    struct tm tmInfo_22; 
    tmInfo_22 = *localtime( &rwTime );
    tmInfo_22.tm_mon = iM - 1;
    tmInfo_22.tm_mday = iD; 
    tmInfo_22.tm_year = iY - 1900;
    mktime( &tmInfo_22 );
    cout << "tmInfo_22 RESULt: " << tmInfo_22.tm_wday << endl;
}

int main()
{
    int iMM=12, iDD=9, iYY=2009;
    strTime( iMM, iDD, iYY );
}

and my question is: What's the difference between these 2 sets of code? Either way, I can achieve the same thing. The notable difference is the first 2-lines from the each set and I have to admit that I didn't understand all of it. So, can anyone kindly explain it to me please? Also, dose one have any advantage(s)/disadvantage(s) over other? Cheers!!


Just for the sake of completeness, this the code I ended up with, which gives me the desired result. So, basically it's for the future reference:

#include <iostream>
#include <fstream>
#include <ctime>

using std::cout;
using std::endl;
using std::string;

tm testTime( int iM, int iD, int iY );

int main()
{
    char tmBuff[20];
    int iMM=12, iDD=9, iYY=2009;

    tm myDate = testTime( iMM, iDD, iYY );
    strftime( tmBuff, sizeof(tmBuff), "%a, %b %d, %Y", &myDate );
    cout << "TESt PRINt TIMe: " << tmBuff << endl;
}

tm testTime( int iM, int iD, int iY ) 
{
    time_t rwTime; 

    struct tm tmTime;
    tmTime = *localtime( &rwTime );

    tmTime.tm_mon = iM - 1;
    tmTime.tm_mday = iD; 
    tmTime.tm_year = iY - 1900;
    mktime( &tmTime );
    return tmTime;
}

NOTE that it does require the *localtime( &rwTime ) to be specified (even though tmTime is getting overwritten afterwards) otherwise the Year(%Y) in the strftime() doesn't work. Thanks to all for helping. Cheers!!

Was it helpful?

Solution

Both versions are valid code, but I got several remarks on this:

In the first version you work on a data structure which you don't own. tmInfo_11 points to memory which is provided and managed by localtime(). This may lead to unwanted side effects when your code grows. So I'd consider it bad style.

The second version is good style, but runs probably slower, because the data structure will copied. But you have to run it really, really often to see a considerable difference.

In the second version I assume you can omit the call to localtime(), because you overwrite the result anyway, except for time entries which you obviously don't use. In the first version you cannot omit localtime(), because you need the pointer to its memory which you use.

You said you haven't understood the differences between the two versions. So I would recommend to revisit the lesson about pointers and when they are valid and when not in a good textbook, again.

OTHER TIPS

The second variant copies the data of the tm structure to your own structure, while the first just uses the pointer to the (static) structure in localtime.

It's the first two lines of both sections that are key. localtime() creates it's output in a static buffer and if you just take a pointer to what it produces - as in the first section - and then call it again, you may find it overwrites what your first pointer points to.

The second example is slightly better as you're effectively copying the whole object although in a multithreaded environment there's still a chance that this could end up with a corruption.

Much better to use localtime_r() which allows you to pass the buffer as a parameter so you don't get this issue.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top