I'm using now() and millis() to trigger events after a certain time has passed. I am aware, and it's also easily found on the web, that millis() rolls over after a certain time has passed and for code that has to run indefinitely you have to handle this.

However I am not aware of if now() can do the same at some point. I mean it does count the seconds from the 1.1.1970 so just regarding this fact, it should not roll over. However, just like millis() this has to be counted somewhere no? How does it work?

  • 3
    What now() are you talking about? Could you give a reference? – Edgar Bonet Oct 12 at 14:22
  • @EdgarBonet probably arduino.cc/en/Reference/CurieTimeNow – Michel Keijzers Oct 12 at 14:26
  • he asks about Epoch seconds in Arduino, as used by the TimeLib – Juraj Oct 12 at 14:27
  • It may be worth noting that you don't necessarily have to "handle" millis() rollover; you just have to prepare your comparison correctly, and there is no rollover problem, as long as you are trying to compare durations smaller than the maximum millis() value. – jose can u c Oct 12 at 14:37
up vote 3 down vote accepted

If now() is from the TimeLib.h library, then this definition:

typedef unsigned long time_t;

indicates time_t is 32-bit unsigned value. Since it represents seconds since 1970-Jan-01 00:00:00, it will experience a rollover when representing dates past approximately 2106 (1970-Jan-01 + 2^32 seconds). Being unsigned, it also cannot represent dates earlier than 1970-Jan-01.

This is slightly different than the 2038 Rollover Problem, which occurs when a system defines a time_t as a signed 32-bit integer, and thus experiences this rollover earlier, in year 2038.

All of this depends on how/where the type time_t is defined for your CPU architecture, and this answer assumes an 8-bit AVR like Arduino Uno. If you use a different architecture, for which TimeLib.h has a different type definition, read the source code to find out exactly what you're dealing with.

  • sorry, long is 32 bits on 32 bits system too – Juraj Oct 12 at 17:21
  • arm gcc and xtensa compiler have time_t as signed long – Juraj Oct 12 at 17:28
  • Yes, it's highly architecture dependent. – jose can u c Oct 12 at 17:40
  • Thank you, this is the answer I was looking for. – Streamline Oct 13 at 8:08

now() is a function that is specific to Intel Curie based boards.

It returns an unsigned long (which on a 32-bit system is the same as an unsigned int) and so can provide the number of seconds since 1/1/1970 up until the year 2106, at which point it will roll over.

If you plan on having your system run continuously for more than the next 88 years you will have to deal with that rollover correctly, including:

  • Using subtraction to "wrap around" your calculations
  • Not trying to calculate any periods longer than 136 years

Time represented in seconds from 1970-01-01 is called Epoch or Unix time. Function now() and similar functions in Arduino libraries returning 'epoch' use 32-bit representation. Some use the time_t type defined in basic includes distributed with the compiler (types.h). On some compilers or in many time and RTC libraries the 32-bit type is signed allowing to represent time before 1970, on some system the type is unsigned.

The signed 32 bit type for epoch time overflows in 2038 (Year 2038 problem). The unsigned 32-bit overflows in 2106.

I use the TimeLib library and it uses the time_t type defined on SAMD and ESP in type.h distributed with the compiler. ARM GCC has time_t as long, which is signed 32 bit type. The same for ESP boards with xtensa compiler. time_t for AVR is defined in the TimeLib library as unsigned 32bit type and overflows in 2016.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.