This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

c2000 cgt 15.x.y time.h changes



I had been using cgt 6.4.x and some of the standard time functions in time.h.

With _tz.timezone = 0, a date of October 16, 2015 16:29:00 GMT would produce a time_t of 1445444940 with mktime().

When I use cgt 15.x.y, the same timezone and GMT date/time produces a different time_t with mktime() of 1445423340

  • I don't see how that could possibly be.  For the TI time functions (which use Epoch 1900), both of those time_t values are on 1945-10-21.  Here is my program demonstrating this; you can run it under CCS.  If this does not answer your question, please post the code demonstrating that you get those values for that date.

    #include <stdio.h>
    #include <time.h>
    
    int main()
    {
        _tz.timezone = 0;
    
        time_t now_t = time(NULL);
        struct tm now_tm = *gmtime(&now_t);
        printf("now:  %lu\n", (unsigned long)now_t);
        printf("now:  %s\n", ctime(&now_t));
    
        struct tm then_tm = now_tm;
        then_tm.tm_year = 2015 - 1900;
        then_tm.tm_mon = 9; /* October */
        then_tm.tm_mday = 16; /* 16th */
        then_tm.tm_hour = 16;
        then_tm.tm_min = 29;
        then_tm.tm_sec = 0;
        time_t then_t = mktime(&then_tm);
        printf("then: %lu\n", (unsigned long)then_t);
        printf("then: %s\n", ctime(&then_t));
    
        time_t val1_t = 1445444940;
        printf("val1: %s\n", ctime(&val1_t));
    
        time_t val2_t = 1445423340;
        printf("val2: %s\n", ctime(&val2_t));
    }
    
  • Hi Archaeologist, thanks for responding.

    The range of the values I posted earlier were adjusted for 1970<->1900 epoch difference 2208988800.

    1445012940 (1970 epoch start)

    +2208988800 (1900 epoch start -> 1970 epoch start)

    =3654001740

    which is right and what 6.4.9 seems to have calculated correctly.

    Here are some screenshots from a live debug session on an F28035.

    CGT 6.4.9

    CGT 15.12.1

    The difference curiously seems to be 21600.  After looking at RTS source in mktime.c, 15.12.1 has

    return result + (_tz.timezone - EPOCH_TZONE);

    while 6.4.9 has only

    return result;

  • Rather than mess with a correction factor, you should set -D__TI_TIME_USES_64 on the command line to use the 64-bit time_t, which uses the POSIX epoch. In the meantime, I'll study your test case.
  • I think your correction factor is wrong. I think it should be 2208967200. Don't forget that the TI epoch is Jan 1, 1970 midnight CST, not GMT, so it's six hours off, which is 21600 seconds.

    In the old code, it was assumed that _tz.timezone would always be 21600, meaning CST. The new code does not make that assumption.
    In the mktime.c for 15.12.1, for TI epoch, _tz.timezone is by default 21600, and EPOCH_TZONE is 21600, so in the default case, this amounts to result+0, exactly as it worked before. When you set _tz.timezone=0, you are exposing a bug in 6.4.9
  • In RFC 868 it is 2208988800, but now that you mention the fact that TI epoch is at CST and not GMT, the 21600 difference makes sense. I wanted to avoid having to do 64 bit math in the code, but making the adjustment for 6.4.9 is easy enough. Thanks Archaeologist!
  • After reviewing further, it seems there is an issue with the sign of _tz.timezone and perhaps with localtime vs gmtime.

    By default, _tz.timezone = 21600, but shouldn't it be -21600 for CST (GMT - 6)?  Maybe I have the definition reversed?

    Let's take an arbitrary date as an example,

    Feb 22, 2016 18:50:31 GMT = 3665155831 (POSIX 1456167031 + 2208988800)

    time_t u1,u2;
    struct tm t1,t2;
    _tz.timezone = 21600;
    t1.tm_hour = 18;
    t1.tm_min = 50;
    t1.tm_sec = 31;
    t1.tm_mon = 1;
    t1.tm_mday = 22;
    t1.tm_year = 116;
    u1 = mktime(&t1);
    t1=*localtime(&u1);
    t2=*gmtime(&u1);
    u2 = mktime(&t2);
    
    _tz.timezone = 0;
    u1 = mktime(&t1);
    t1=*localtime(&u1);
    t2=*gmtime(&u1);
    u2 = mktime(&t2);

    6.4.9

    With _tz.timezone = 21600,

    u1 = 3665155831 which is the correct NTP epoch timestamp (Jan 1, 1900 midnight GMT), and not the TI epoch timestamp (Jan 1, 1900 midnight CST).

    t2 is ahead 6 hours of t1 and u2 = 3665177431.  I thought gmtime was supposed to create a time structure that was GMT, and localtime would have timezone offset applied.  Are gmtime and localtime are swapped?

    With _tz.timezone = 0, u1 = u2 = 3665155831 as expected.

    So it seems in 6.4.9, mktime does not care about timezone.  It produces NTP epoch timestamp and not the TI epoch timestamp.  Also, localtime doesn't apply _tz.timezone, while gmtime does (was expecting opposite behavior).

    15.12.1

    With _tz.timezone = 21600,

    u1 = 3665155831 and t2 is ahead 6 hours of t1 and u2 = 3665177431 = u1 + _tz.timezone, same as in 6.4.9.

    With _tz.timezone = 0,

    u1 = u2 = 3665134231, which is is the TI epoch (NTP epoch - 21600) ... but now we are subtracting the offset??

  • The C standard says that the method of implementing the time zone is implementation-defined. For better or for worse, TI has defined the timezone field to be a non-negative number. 21600 represents CST (-0600), and 0 represents GMT (+0000)

    Your example is not quite right.

    POSIX 1456167031, equivalent to NTP 3665155831, represent these equivalent times:
    Mon Feb 22 18:50:31 UTC 2016
    Mon Feb 22 12:50:31 CST 2016

    When you specified the initial values for "struct tm t1", you set it to a different time, "Mon Feb 22 18:50:31 CST 2016," which has TI epoch timestamp 3665155831 as well. Remember, the input to mktime is expressed in local time. Furthermore, because of this, it is not legitimate to pass the output of gmtime to mktime.

    In 6.4.9, localtime should respect _tz.timezone and it does not, which is a bug. Because the source code for gmtime calls localtime, this bug also affects gmtime.
  • OK, I understand better now. When you say TI has defined timezone to be non-negative, what about GMT+x offsets? _tz.timezone could be negative since it's a signed integer though right? So -3600 would mean GMT + 0100h?
  • I think you're right about _tz.timezone; when I said Ti has defined the timezone field to be non-negative, that was my own conclusion, it isn't written that way necessarily in the code. It does appear to be the negative of the time zone adjustment, in seconds. I'll have to think about whether this might expose another bug when dealing with GMT+ times.