esp-idf: time_t is 32-bit wide, please change to 64-bit to make applications Y2K38 safe (IDF-350)

The time_t base type on which all unix-timestamp (seconds after 1970-01-01) related functions (such as gettimeofday) do rely on, is only 4 bytes (32-bit) wide. It is suggested to use an 8 byte (64-bit) variable here, as otherwise all unix-timestamps after 2038-01-18 will be wrong. To sketch this, I coded an example (main.c), which shows the exact problem. Notably is, that not only the current wall-clock time is affected by this, also calculations on the time (for example, calendar events and the like) which result in a value higher than the noted limit in 2038, are affected. This could become at some time a serious issue, so it would be best to act soon. See also the wikipedia page on this problem.

So it would be very appreciating to change the time_t base type to an “signed long long” type.

The current output of my sample code can be seen here:

I (508) example: sizeof(time_t): 4 (32-bit)
I (1508) example: Time now: 000000007FFFFFF8 (2038-01-19 03:14:00)
I (2508) example: Time now: 000000007FFFFFF9 (2038-01-19 03:14:01)
I (3508) example: Time now: 000000007FFFFFFA (2038-01-19 03:14:02)
I (4508) example: Time now: 000000007FFFFFFB (2038-01-19 03:14:03)
I (5508) example: Time now: 000000007FFFFFFC (2038-01-19 03:14:04)
I (6508) example: Time now: 000000007FFFFFFD (2038-01-19 03:14:05)
I (7508) example: Time now: 000000007FFFFFFE (2038-01-19 03:14:06)
I (8508) example: Time now: 000000007FFFFFFF (2038-01-19 03:14:07)
I (9508) example: Time now: FFFFFFFF80000000 (1901-12-13 20:45:52)
I (10508) example: Time now: FFFFFFFF80000001 (1901-12-13 20:45:53)
I (11508) example: Time now: FFFFFFFF80000002 (1901-12-13 20:45:54)
I (12508) example: Time now: FFFFFFFF80000003 (1901-12-13 20:45:55)
I (13508) example: Time now: FFFFFFFF80000004 (1901-12-13 20:45:56)
I (14508) example: Time now: FFFFFFFF80000005 (1901-12-13 20:45:57)
I (15508) example: Time now: FFFFFFFF80000006 (1901-12-13 20:45:58)
I (16508) example: Time now: FFFFFFFF80000007 (1901-12-13 20:45:59)
I (17508) example: Time now: FFFFFFFF80000008 (1901-12-13 20:46:00)

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 3
  • Comments: 24 (13 by maintainers)

Commits related to this issue

Most upvoted comments

Hi @remcoNL,

Glad you found a workaround!

We’ve decided to push this back from the v4.0 release, as we’re already making a lot of other newlib changes. Sorry for the inconvenience. The current plan is as follows:

  • 64-bit time_t will be supported in IDF v4.1 as an optional configuration. It may require building a custom toolchain where newlib is configured with 64-bit time_t (this process will be documented).
  • 64-bit time_t is planned to become default in IDF v5.0

We’re currently averaging a major version per year, so there should still be plenty of time between the v5.0 release and the 2038 deadline.

OTA updating a firmware with 32-bit time_t to 64-bit time_t should work fine, also (assuming the OTA update is complete before 2038.)

That’s a relief…

I will now subtract 883612800 seconds and dates and weekdays are the same again! Also this gives you an extra 28 years to make the update!

https://math.stackexchange.com/questions/536847/how-often-in-years-do-calendars-repeat-with-the-same-day-date-combinations-juli

Currently we supply newlib as a set of pre-built libraries. time_t size is fixed at the time these libraries are built. We plan to also allow for doing custom builds of newlib in IDF. This would allow changing sizeof(time_t) and other things.

For the change of default time_t size, we will have to wait until one of the major releases, since that would be a breaking change for some existing applications.

Hi @themadsens,

We have this on our internal list of breaking changes that we plan to make in ESP-IDF V5.0 (the toolchain support was unfortunately too late to be included in V4.0, so V5.0 is our next opportunity to introduce this). I’m afraid there’s no public ticket apart from this one, though.

Please remember struct timeval from gettimeofday() As of IDF 4.0 the tv_sec member is a long (defined in lwip/sockets.h(!?)

Thanks for pointing this out and sorry noone replied when you first commented about it. This is something that LWIP supports (for platforms without compliant sys/time.h). However, we don’t use this in ESP-IDF:

Building a custom toolchain with SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS and using it with ESP-IDF is supported since V4.1, so if you find anything else that doesn’t work in this configuration (on V4.1 or newer) then please open a new GitHub issue for it and we’ll fix it.

Hi @vielmetti ,

Thanks for the reminder about the GitHub Milestones feature. As you can see, we haven’t been using it. We plan to start publishing a version roadmap soon, but at the moment there isn’t one publically accessible.

Currently the plan is for V4.0 to be in beta release by the end of the year, for a final release in early 2019.

Or alternatively make it an unsigned 32-bit integer postponing the 32-bit overflow by further 68 years.