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.

CC3220MODA: mktime unexpected behavior

Part Number: CC3220MODA

Hello all,

I use the TI CCS 11, CLANG v1.3.0LTS, simplelink_cc32xx_sdk_5_30_00_08, XDCtools 3.62.1.16 and a CC3220MODASF - based board.
The application uses the TIRTOS.

I want to convert a struct tm base value to the UTC epoch counter using mktime.

This is done in the function convertTm2Epoch, that in turn is called by the function testTime64 three times with a different value of the parameter daylightSaving.
The function should only convert - not to set anything.

static void convertTm2Epoch( struct tm *ptm, int daylightSaving )
{
  char *atime = "Ignored";
  time_t epoch;
  time_t tzone;
  memset((void*)ptm, 0, sizeof( struct tm));

  /* 2022/01/01 00:00:00 */
  ptm->tm_sec = 0;
  ptm->tm_min = 0;
  ptm->tm_hour = 0;
  ptm->tm_mday = 1;
  ptm->tm_mon = 0;
  ptm->tm_year = 122;
  ptm->tm_isdst = daylightSaving;  /* positive if daylight saving time is in effect, zero if it is not, and negative if the information is not available  */

  atime = asctime( ptm );
  epoch = mktime( ptm ); /* TI: modifies tm.tm_isdst to -1 */

#if defined(__x86_64__)
  tzone = timezone;
#else
#include <ti/net/utils/clock_sync.h>
  tzone = (time_t)ClockSync_getTimeZone() * 60; /* function returns minutes */
#endif

  epoch -= tzone;
  
  /* convert 64 bit values to 32 bit values - needed because TI snprintf doesn't support 64 bit values */
  /* inside the debugger the same values are shown  - in  */
  LOG_INFO( "Time: daylight %d (after mktime %d), %s, epoch %ld, timezone %d, time_t %d bytes",
    daylightSaving, ptm->tm_isdst, atime, (uint32_t)epoch, (int32_t)tzone, (uint32_t)sizeof(time_t) );
}


static void testTime64( void )
{
  struct tm tm;

  convertTm2Epoch( &tm, 1 );
  convertTm2Epoch( &tm, 0 );
  convertTm2Epoch( &tm, -1 );
}

I have two test systems:
* X86 - base cygwin system located in Germany, UTC/ GMT + 1 hour + 1 hour daylight saving
* custom board with TI module.

The site www.epochconverter.com/ shows the epoch counter of 1640995200 for the used values in the struct pm.

1. UTC and Unix Epoch counter

Cygwin:

Time: daylight 1  (after mktime 0), Sun Jan 1 00:00:00 2022, epoch 1640991600, timezone -3600, time_t 8 bytes
Time: daylight 0  (after mktime 0), Sun Jan 1 00:00:00 2022, epoch 1640995200, timezone -3600, time_t 8 bytes
Time: daylight -1 (after mktime 0), Sun Jan 1 00:00:00 2022, epoch 1640995200, timezone -3600, time_t 8 bytes


As mentioned in the mktime documentation the values of the struct tm are changed as expected (inspected by the debugger).
The returned values of the epoch counters in combination with the daylight saving parameter are as expected.

Board:

Time: daylight 1  (after mktime -1), Sun Jan 1 00:00:00 2022, epoch 1641016800, timezone 0, time_t 8 bytes
Time: daylight 0  (after mktime -1), Sun Jan 1 00:00:00 2022, epoch 1641016800, timezone 0, time_t 8 bytes
Time: daylight -1 (after mktime -1), Sun Jan 1 00:00:00 2022, epoch 1641016800, timezone 0, time_t 8 bytes

The returned values are always the same and have an additional unexpected offset of 21600.
The value 1641016800 results in GMT: Saturday, 1. January 2022 06:00:00.

The function ClockSync_getTimeZone returns zero.
Thats is correct because no time zone related functions called in advance.

For test I implemented a call to ClockSync_setTimeZone( 0 ) which doesn't change anything.

Info: If I call ClockSync_setTimeZone( 21600 / 60 ) the function returns the same epoch counter as the cygwin part.

If my procedure is right and the offset exists, I have to pay attention to the value of 21600 because my application exchanges date and time information in UTC.

Are there any wrong points in my procedure?
Where does the value of 21600 comes from and how can I get it?
Can I be sure that the value will not change?

Additional Information: The TI cc in combination with the define __TI_TIME_USES_64 I get the same result as shown using clang.
In the file C:\ti\ccs1100\ccs\tools\compiler\ti-cgt-arm_20.2.5.LTS\lib\src\mktime.c I found the following line:
#define __TI_EPOCH_TZONE 21600 /* CST (seconds WEST of UTC) */
That value matches exactly the unexpected offset to the resulting epoch counter.

2. daylight saving time is ignored
Since the returned epoch counter value is always the same regardless of the given tm.isdst and tm.isdst is always set to -1 by mktime, I assume the application needs to take care of daylight saving time.
I am right?

Best regards,
Roman

  • Hello Roman,

    Looking at mktime.c it appears as if there is an offset of -21600 for EPOCH_TZONE which sets it to CST which is the Dallas time zone where TI headquarters is located.

    This block of code explains both issues you are having. 

    1.) Daylight savings time is assumed to already be used when the time is given

    2.) At the end the result is returned we subtract 21600 and converts the time to cst. I honestly dont know why this is done.

    You can account for this in your code or change the EPOCH_TZONE to 0 which will be at UTC. Unfortunately I cant be of more help as this problem seems to be a c lib error.

    Kind Regards,

    Rogelio

  • Hello RogelioD,

    many thanks for your answer.
    Because of the EPOCH ZONE is not exported and and the statically LIBS were built with that defines leading to that time offset I think I have to handle that offset manually in the application.

    Does anybody now how to determine that this offset is active?
    I am a little bit afraid that TI will "fix" that behavior in the future.

    Best Regards,
    Roman