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 意外行为

Guru**** 647180 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1130847/cc3220moda-mktime-unexpected-behavior

器件型号:CC3220MODA

大家好、

我使用 TI CCS 11、clang v1.3.0LTS、simplelink_cc32xx_sdk_5_30_00_08、XDCtools 3.62.1.16和基于 CC3220MODASF 的板。
应用程序使用 TIRTOS。

我想使用 mktime 将 struct tm 基值转换为 UTC epoch 计数器。

这在函数 converttm2Epoch 中完成、函数 testTime64使用参数 daylightSaving 的不同值三次调用该函数。
该函数只应转换-不应设置任何内容。

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 );
}

我有两个测试系统:
* x86 -德国的基本 cygwin 系统、UTC/ GMT + 1小时+ 1小时夏令时
*带 TI 模块的定制板。

站点 www.epochconverter.com 显示结构 PM 中使用的值的 epoch 计数器1640995200。

UTC 和 Unix Epoch 计数器

Cygwin:

时间:夏令时1 (在 mktime 0之后)、Sun Jan 1 00:00:00 2022、epoch 1640991600、timezone -3600、time_t 8字节
时间:夏令时0 (在 mktime 0之后)、Sun Jan 1 00:00:00 2022、epoch 1640995200、时区-3600、time_t 8字节
时间:日光-1 (在 mktime 0之后)、Sun Jan 1 00:00:00 2022、epoch 1640995200、时区-3600、time_t 8字节


mktime 文档中所述、struct tm 的值会按预期发生变化(由调试器检查)。
epoch 计数器的返回值与夏令时参数的组合符合预期。

电路板:

时间:夏令时1 (mktime -1之后)、Sun Jan 1 00:00:00 2022、epoch 1641016800、时区0、time_t 8字节
时间:夏令时0 (在 mktime -1之后)、Sun Jan 1 00:00:00 2022、epoch 1641016800、时区0、time_t 8字节
时间:夏令时-1 (mktime -1之后)、Sun Jan 1 00:00:00 2022、epoch 1641016800、时区0、time_t 8字节

返回的值始终相同、额外的意外偏移为21600。
值1641016800得出 GMT:星期六、1。 2022年1月06:00:00。

函数 ClockSync_getTimeZone 返回零。
这是正确的、因为没有预先调用与时区相关的函数。

在测试中,我实现了对 ClockSync_setTimeZone( 0)的调用,该调用不会改变任何内容。

INFO:如果我调用 ClockSync_setTimeZone (21600 / 60),函数将返回与 cygwin 部件相同的 epoch 计数器。

如果我的程序正确且存在偏移、我必须注意21600的值、因为我的应用程序在 UTC 中交换日期和时间信息。

我的程序中是否有任何错误点?
21600的价值来自哪里?如何获得?
我可以确定该值不会改变吗?

其他信息:TI cc 与 define __TI_TIME_USS_64结合使用时,我获得的结果与使用 clang 时所示的结果相同。
在文件 C:\ti\ccs1100\ccs\tools\compiler\ti-cgt-arm_20.2.5.LTS \lib\src\mktime.c 中、我找到以下行:
#define __TI_eparch_TZONE 21600 /* CST (UTC 以西的秒数)*/
该值与产生的 epoch 计数器的意外偏移完全匹配。

2.忽略夏令时
由于无论给定的 TM.isdst 和 TM.isdst 始终将返回的 epoch 计数器值设置为-1 (通过 mktime)、因此我假设应用需要处理夏时制。
我是对的吗?

此致、
罗马

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Roman、

    通过查看 mktime.c、可以看出 epoch TZONE 的偏移量为-21600、该偏移量将其设置为 CST、这是 TI 总部所在的达拉斯时区。

    此代码块解释了您遇到的两个问题。  

    1) 假设在给定时间后已使用夏令时

    2) 最后返回结果、我们减去21600并将时间转换为 CST。 老实说,我不知道为什么会这样做。

    您可以在代码中对此进行说明、或将 epoch TZONE 更改为0、该值将在 UTC。 不幸的是、这个问题似乎是一个 c lib 错误、因此我没有更多帮助。

    此致、

    Rogelio

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    RogelioD、您好!

    非常感谢您的回答。
    由于没有导出 epoch 区域、并且静态 libs 是使用该定义构建的、从而导致该时间偏移、我认为我必须在应用中手动处理该偏移。

    现在有人如何确定该偏移是否处于活动状态?
    我有点担心 TI 将来会"修复"这种行为。

    此致、
    罗马