Hi Guys, I am trying to use the default c datetime functions, but it seems like there are bugs in the code.
When create a struct tm type from a timestamp, it is 30 years and 1 day off !!?! (I tried multiple timestamps, The time is constantly right):
#include <stdint.h>
#include <time.h>
#include <stdio.h>
void setup() {
Serial.begin(9600);
}
void loop()
{
Serial.println("Timestamp: 1537216259 is equivalent to");
Serial.println("GMT time: 2018-09-17 20:30:59");
Serial.println();
time_t t = 1537216259;
tm* dt = gmtime(&t);
dt->tm_isdst = 0;
Serial.print("Year should be 2018 - 1900 = 118, got: "); Serial.println(dt->tm_year);
Serial.print("Month should be 09 - 1 = 8, got: "); Serial.println(dt->tm_mon);
Serial.print("Day should be 17, got: "); Serial.println(dt->tm_mday);
Serial.print("Got Time: ");
Serial.print(dt->tm_hour); Serial.print(":");
Serial.print(dt->tm_min); Serial.print(":");
Serial.println(dt->tm_sec); Serial.println();
while(1);
}
Prints:
Timestamp: 1537216259 is equivalent to
GMT time: 2018-09-17 20:30:59
Year should be 2018 - 1900 = 118, got: 148
Month should be 09 - 1 = 8, got: 8
Day should be 17, got: 16
Got Time: 20:30:59
Though not specified in the standard, it is often expected that time_t is a signed integer representing an offset in seconds from Midnight Jan 1 1970... i.e. 'Unix time'. This implementation uses an unsigned 32 bit integer offset from Midnight Jan 1 2000. The use of this 'epoch' helps to simplify the conversion functions, while the 32 bit value allows time to be properly represented until Tue Feb 7 06:28:15 2136 UTC. The macros UNIX_OFFSET and NTP_OFFSET are defined to assist in converting to and from Unix and NTP time stamps.
Ah thanks for the info, I was suspecting maybe they moved the AVR epoch 30 years into the future to extend the present working age a bit, but what confuses me is the one day off issue, on my mega only it seems. Very strange.
I first wrote some code and ran it on my computer GNU C++ compiler and it worked fine, then I saw these issues when running on the AVR.
mangelozzi:
but what confuses me is the one day off issue, on my mega only it seems. Very strange.
There are 7 leap days between 1 Jan 1970 and 1 Jan 2000 (1972, '76, '80, '84, '88, '92, '96),
but 8 leap days between 17 Sep 2018 and 16 Sep 2048 (2020, '24, '28, '32, '26, '40, '44, '48).
The difference is 30*365+7 days in both cases.
Ah thanks, I see see, I didnt realise there were non AVR arduino boards.
So heres the other half of the puzzle, converting from tm to time, and after much confusion, I finally narrowed it down to a single print statement which is changing the timestamp?!?! :o I kid you not, if you uncomment out the line as indicated below, the correct timestamp is displayed! Shows something going on I don't understand, which makes me concerned to use the function.