Home > Enterprise >  Why am I getting incorrect time using tm time?
Why am I getting incorrect time using tm time?

Time:08-31

I am subtracting the current time with one minute earlier, however C is saying the difference is 18000 seconds, which is like 300 minutes (4 hours). Really confused as to why this is happening. This is my code:

#include <stdio.h>
#include <time.h>
#include <iostream> 

int main(){
    time_t timer; 
    struct tm t = {0}; 
    double seconds; 
    
    t.tm_year = 122; //2022
    t.tm_mon = 7 //august
    t.tm_mday = 29; //29
    t.tm_hour = 21; //10pm
    t.tm_min = 35; //35
    t.tm_sec = 0; 

    time(&timer); //get current time
    seconds = difftime(timer, mktime(&t)); 

    std::cout << seconds; 
}

CodePudding user response:

The time function in the C library deals with UTC time while mktime assumes your local time. This is explicit in the documentation.

time() returns the time as the number of seconds since the Epoch, 1970-01-01 00:00:00 0000 (UTC).

The mktime() function converts a broken-down time structure, expressed as local time, to calendar time representation.

Consider this code:

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <iostream> 

int main(){
    struct tm t; 
    memset(&t,0,sizeof(tm));
    t.tm_year = 2022 - 1900;
    t.tm_mon = 8 - 1;  
    t.tm_mday = 29; 
    t.tm_hour = 23;
    t.tm_min = 28; 
    t.tm_sec = 0;
    t.tm_isdst = 1;
    
    time_t mktm = mktime(&t);
    time_t timer = time(0);

    double seconds = difftime(timer,mktm); 
    std::cout << seconds << std::endl;
    std::cout << mktm << std::endl;
    std::cout << timer << std::endl;

    struct tm local;
    localtime_r( &mktm, &local );
    std::cout << "gmtoff:" << local.tm_gmtoff << std::endl;
}

Observe that I passed t.tm_isdst=1 because I am in Chicago which is currently on daylight and I get this:

$ g   /tmp/test2.cpp -o ./test2
$ ./test2
30
1661833680
1661833710
gmtoff:-18000

So this is telling me that the time structure is just 30 seconds before the current time, which is your intended result. I also requested to print the localtime gmt offset which is minus 18,000 seconds (-5 hours), which seems correct.

Note that the timestamps 1661833680 and 1661833710 are both in GMT as you can check on epochconverter.com

enter image description here

Now when I run this exact code on Godbolt Compiler Explorer I get a different result:

18031
1661816160
1661834191
gmtoff:0

So it is telling me now that the difference is now 5 hours. This is because it assumed that the time I was passing was in London time! But now it is 4:41am in London.

Notice that the gmtoffset is now zero indicating that this machine is in London (or set its timezone as UK).

So what I believe it is happening in your case is that you are somewhere in UTC-4 (New York?) and logged on a computer in the UK or using compiler explorer as myself.

CodePudding user response:

I am having windows using bash.exe

$ /cygdrive/c/Windows/System32/tzutil.exe /s "Central America Standard Time"
$ date " %a %d-%b-%Y %I:%M:%S %Z"
Tue 30-Aug-2022 01:10:01 CDT
$ /cygdrive/c/Windows/System32/tzutil.exe /g
Central America Standard Time
$ /cygdrive/c/Windows/System32/tzutil.exe /s "E. South America Standard Time"
$ date " %a %d-%b-%Y %I:%M:%S %Z"
Tue 30-Aug-2022 01:10:48 CDT
$ ./a.out
Seconds: 6191
mktm   : 1661833680
timer  : 1661839871
gmtoff : -18000
$ tzutil /s "India Standard Time"
$ ./a.out
Seconds: 47632
mktm   : 1661792280
timer  : 1661839912
gmtoff : 19800

Hence the output of a.out varies based on system timings like the way of two planets from two galaxies having same timing using TZ environment variable (at Linux oriented OS). I have set my system back to IST using admin privileges again.

C:> C:\Windows\System32\tzutil.exe /g
India Standard Time

Same thing applicable at browser inside system/mobile/external applications like ATM/... when web server/any application at a system using different TZ/tzutil location changes.

  • Related