From 1fb575d98b17ec3c2f851206acc0a535efa45543 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schneider?= Date: Thu, 30 Sep 2021 14:13:46 +0200 Subject: [PATCH 1/2] Fix: setDate() handling century flag correctly --- src/DS3231.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/DS3231.cpp b/src/DS3231.cpp index 36a4935..bd7ae77 100644 --- a/src/DS3231.cpp +++ b/src/DS3231.cpp @@ -532,12 +532,13 @@ setDate -----------------------------------------------------------*/ void DS3231::setDate(uint8_t day, uint8_t month, uint16_t year) { + uint8_t century = year / 100; year = year % 100; //Converting to 2 Digit Wire.beginTransmission(DS3231_ADDR); Wire.write(0x04); Wire.write(bin2bcd(day)); - Wire.write(bin2bcd(month)); + Wire.write(bin2bcd(month) | (century >= 20 ? 128 : 0)); Wire.write(bin2bcd(year)); Wire.endTransmission(); } From 1ca4192d74a43986a818eb09e247121bb5e7d1c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Schneider?= Date: Thu, 30 Sep 2021 14:45:06 +0200 Subject: [PATCH 2/2] Fix: correct Unix / Arduino epoch handling `setDate()` handling 2-digit years as 2000s --- src/DS1307.cpp | 18 +++++++++++++----- src/DS3231.cpp | 22 +++++++++++++++++----- src/RTC.h | 8 ++++---- 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/src/DS1307.cpp b/src/DS1307.cpp index 4c40955..40c4923 100644 --- a/src/DS1307.cpp +++ b/src/DS1307.cpp @@ -372,6 +372,9 @@ setDate -----------------------------------------------------------*/ void DS1307::setDate(uint8_t day, uint8_t month, uint16_t year) { + // If year is 2 digits. + if(year < 100) + year = year + 2000; year = year % 100; //Converting to 2 Digit Wire.beginTransmission(DS1307_ADDR); Wire.write(0x04); @@ -418,13 +421,16 @@ void DS1307::setDateTime(char* date, char* time) setEpoch() -----------------------------------------------------------*/ -void DS1307::setEpoch(time_t epoch) +void DS1307::setEpoch(time_t epoch, bool is_unix_epoch=true) { - time_t rawtime; struct tm epoch_tm, * ptr_epoch_tm; uint16_t year; - rawtime = epoch; - ptr_epoch_tm = gmtime(&rawtime); + // adjust UNIX epoch to ARDUINO epoch, otherwise `tm` struct + // is one year and one (leap) day off. + if(is_unix_epoch) + epoch = epoch - UNIX_OFFSET; + + ptr_epoch_tm = gmtime(&epoch); epoch_tm = *ptr_epoch_tm; setSeconds(epoch_tm.tm_sec); //0x00 - Seconds setMinutes(epoch_tm.tm_min); @@ -439,7 +445,7 @@ void DS1307::setEpoch(time_t epoch) /*----------------------------------------------------------- getEpoch() -----------------------------------------------------------*/ -time_t DS1307::getEpoch() +time_t DS1307::getEpoch(bool as_unix_epoch=true) { time_t epoch; struct tm epoch_tm; @@ -451,6 +457,8 @@ time_t DS1307::getEpoch() epoch_tm.tm_mon = getMonth() - 1; epoch_tm.tm_year = getYear() - 1900; epoch = mktime(&epoch_tm); + if(as_unix_epoch) + epoch += UNIX_OFFSET; return (epoch); } diff --git a/src/DS3231.cpp b/src/DS3231.cpp index bd7ae77..63124c5 100644 --- a/src/DS3231.cpp +++ b/src/DS3231.cpp @@ -532,7 +532,12 @@ setDate -----------------------------------------------------------*/ void DS3231::setDate(uint8_t day, uint8_t month, uint16_t year) { - uint8_t century = year / 100; + uint8_t century; + + // If year is 2 digits. + if(year < 100) + year = year + 2000; + century = year / 100; year = year % 100; //Converting to 2 Digit Wire.beginTransmission(DS3231_ADDR); @@ -582,17 +587,22 @@ setEpoch() https://en.wikipedia.org/wiki/Epoch_(computing) -----------------------------------------------------------*/ -void DS3231::setEpoch(time_t epoch) +void DS3231::setEpoch(time_t epoch, bool is_unix_epoch=true) { uint8_t h_mode, data, century; uint16_t year; struct tm epoch_tm, *ptr_epoch_tm; + // adjust UNIX epoch to ARDUINO epoch, otherwise `tm` struct + // is one year and one (leap) day off. + if (is_unix_epoch) + epoch = epoch - UNIX_OFFSET; + ptr_epoch_tm = gmtime(&epoch); epoch_tm = *ptr_epoch_tm; - century = (epoch_tm.tm_year + 1870) / 100; // Find Century - year = (epoch_tm.tm_year + 1870) % 100; //Converting to 2 Digit + century = (epoch_tm.tm_year + 1900) / 100; // Find Century + year = (epoch_tm.tm_year + 1900) % 100; //Converting to 2 Digit Wire.beginTransmission(DS3231_ADDR); @@ -687,7 +697,7 @@ void DS3231::setEpoch(time_t epoch) /*----------------------------------------------------------- getEpoch() -----------------------------------------------------------*/ -time_t DS3231::getEpoch() +time_t DS3231::getEpoch(bool as_unix_epoch=true) { uint8_t century_bit; uint16_t century; @@ -720,6 +730,8 @@ time_t DS3231::getEpoch() epoch_tm.tm_year = epoch_tm.tm_year + century - 1870; epoch = mktime(&epoch_tm); + if(as_unix_epoch) + epoch += UNIX_OFFSET; return (epoch); } diff --git a/src/RTC.h b/src/RTC.h index e9b6f45..87efdb3 100644 --- a/src/RTC.h +++ b/src/RTC.h @@ -93,8 +93,8 @@ class DS1307 uint8_t getMonth(); uint16_t getYear(); - void setEpoch(time_t epoch); - time_t getEpoch(); + void setEpoch(time_t epoch, bool is_unix_epoch=true); + time_t getEpoch(bool as_unix_epoch=true); void setOutPin(uint8_t mode); bool isOutPinEnabled(); @@ -151,8 +151,8 @@ class DS3231 { void setDate(uint8_t day, uint8_t month, uint16_t year); void setTime(uint8_t hour, uint8_t minute, uint8_t second); - void setEpoch(time_t epoch); - time_t getEpoch(); + void setEpoch(time_t epoch, bool is_unix_epoch=true); + time_t getEpoch(bool as_unix_epoch=true); void setDateTime(char* date, char* time);