Zanduino / MCP7940

Arduino Library to access the MCP7940M, MCP7940N and MCP7940x Real-Time chips
GNU General Public License v3.0
35 stars 22 forks source link

DateTime(0) doesn't resolve correctly to the epoch #60

Closed obdevel closed 3 years ago

obdevel commented 3 years ago

Expected Behavior

A DateTime object initialised to zero should resolve to the unix epoch, i.e. 1/1/1970 00:00:00

I'm trying to initialise the time component to 00:00:00. This seems the easiest way.

Actual Behavior

The actual output is 6/2/2106 6:28:16

Steps to Reproduce the Problem

Minimum reproducible code:

#include <MCP7940.h>

void setup() {
  Serial.begin(115200);

  DateTime dt1 = DateTime(0);
  // DateTime dt1(0); //  produces same result
  Serial.println(dt1.unixtime());
  Serial.print(dt1.day());
  Serial.print("/");
  Serial.print(dt1.month());
  Serial.print("/");
  Serial.print(dt1.year());
  Serial.print(" ");
  Serial.print(dt1.hour());
  Serial.print(":");
  Serial.print(dt1.minute());
  Serial.print(":");
  Serial.print(dt1.second());
  Serial.println();
}

void loop() {
}

Output is:

0
6/2/2106 6:28:16

If I construct the object as

DateTime dt1(1970, 1, 1, 0, 0, 0);

the output is:

2269013504
1/1/2178 0:0:0

Specifications

SV-Zanshin commented 3 years ago

That certainly looks like bug! I'm not sure I need to dig out a MCP7940 to debug this issue, it looks like the issue is in the time classes and not the hardware.

obdevel commented 3 years ago

My current project is not urgent so there is no rush for a fix.

SV-Zanshin commented 3 years ago

The library uses a fork of Jeelabs RTC, which is now maintained by a fork at https://github.com/adafruit/RTClib

This DateTime class is limited to dates starting at 2000-01-01. Passing a UnixTime less than that date causes library underflow errors which explains the output you are seeing. I've changed the call to DateTime() to not allow any date lower than that value.

Changing the library to allow for the full UnixTime range would mean increasing data types everywhere and adding logic. Considering that the MCP7940 can't deal with dates before 2000 the library doesn't need changing.

I will update the wiki as well.

obdevel commented 3 years ago

Thanks Arnd. I don't need dates/times before 2000. I guess I was led astray by the naming of the unixtime() method and assumed it used the Unix epoch like time_t based libraries.

I'll let you close this issue once you've made the update.

SV-Zanshin commented 3 years ago

The library does use UnixTime starting at the correct epoch date, it just doesn't any values less than the number of seconds defined at:

const uint32_t SECS_1970_TO_2000{946684800}; ///< Seconds between year 1970 and 2000