[Time] Fix tm_mon starting at 0 and tm_year at 1900

All over the code there were incorrect assumptions about the offsets in `struct tm`
This commit is contained in:
TD-er
2021-02-03 13:30:14 +01:00
parent c814380db1
commit ee216b01c1
7 changed files with 35 additions and 48 deletions
+1 -1
View File
@@ -486,7 +486,7 @@ void TinyGPSDate::commit()
}
{
const uint16_t newyear = year();
if (newyear < 2020) {
if (newyear < 2021) {
// Looks like it is an old GPS unit not working well with the 1024 week rollover.
struct tm tm;
tm.tm_year = newyear - 1900;
+2 -2
View File
@@ -71,8 +71,8 @@ String Command_DateTime(struct EventStruct *event, const char *Line)
struct tm tm;
int yr, mnth, d;
sscanf(TmpStr1.c_str(), "%4d-%2d-%2d", &yr, &mnth, &d);
tm.tm_year = yr - 1970;
tm.tm_mon = mnth;
tm.tm_year = yr - 1900;
tm.tm_mon = mnth - 1; // tm_mon starts at 0
tm.tm_mday = d;
if (GetArgv(Line, TmpStr1, 3)) {
+14 -27
View File
@@ -40,13 +40,9 @@ struct tm ESPEasy_time::addSeconds(const struct tm& ts, int seconds, bool toLoca
void ESPEasy_time::breakTime(unsigned long timeInput, struct tm& tm) {
uint8_t year;
uint8_t month, monthLength;
uint32_t time;
unsigned long days;
const uint8_t monthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
time = (uint32_t)timeInput;
uint32_t time = (uint32_t)timeInput;
tm.tm_sec = time % 60;
time /= 60; // now it is minutes
tm.tm_min = time % 60;
@@ -55,30 +51,21 @@ void ESPEasy_time::breakTime(unsigned long timeInput, struct tm& tm) {
time /= 24; // now it is days
tm.tm_wday = ((time + 4) % 7) + 1; // Sunday is day 1
year = 0;
days = 0;
int year = 1970;
unsigned long days = 0;
while ((unsigned)(days += (isLeapYear(year) ? 366 : 365)) <= time) {
year++;
}
tm.tm_year = year; // year is offset from 1970
tm.tm_year = year - 1900; // tm_year starts at 1900
days -= isLeapYear(year) ? 366 : 365;
time -= days; // now it is days in this year, starting at 0
days = 0;
month = 0;
monthLength = 0;
uint8_t month = 0;
for (month = 0; month < 12; month++) {
if (month == 1) { // february
if (isLeapYear(year)) {
monthLength = 29;
} else {
monthLength = 28;
}
} else {
monthLength = monthDays[month];
uint8_t monthLength = monthDays[month];
if (month == 1 && isLeapYear(year)) { // February
monthLength = 29;
}
if (time >= monthLength) {
@@ -87,8 +74,8 @@ void ESPEasy_time::breakTime(unsigned long timeInput, struct tm& tm) {
break;
}
}
tm.tm_mon = month + 1; // jan is month 1
tm.tm_mday = time + 1; // day of month
tm.tm_mon = month; // Jan is month 0
tm.tm_mday = time + 1; // day of month start at 1
}
@@ -415,9 +402,9 @@ String ESPEasy_time::getDateString(char delimiter) const
String ESPEasy_time::getDateString(const struct tm& ts, char delimiter) {
// time format example with ':' delimiter: 23:59:59 (HH:MM:SS)
char DateString[20]; // 19 digits plus the null char
const int year = 1970 + ts.tm_year;
const int year = 1900 + ts.tm_year;
sprintf_P(DateString, PSTR("%4d%c%02d%c%02d"), year, delimiter, ts.tm_mon, delimiter, ts.tm_mday);
sprintf_P(DateString, PSTR("%4d%c%02d%c%02d"), year, delimiter, ts.tm_mon + 1, delimiter, ts.tm_mday);
return DateString;
}
@@ -494,7 +481,7 @@ int ESPEasy_time::year(unsigned long t)
struct tm tmp;
breakTime(t, tmp);
return 1970 + tmp.tm_year;
return 1900 + tmp.tm_year;
}
int ESPEasy_time::weekday(unsigned long t)
@@ -615,7 +602,7 @@ int ESPEasy_time::dayOfYear(int year, int month, int day) {
}
void ESPEasy_time::calcSunRiseAndSet() {
int doy = dayOfYear(tm.tm_year, tm.tm_mon, tm.tm_mday);
int doy = dayOfYear(tm.tm_year, tm.tm_mon + 1, tm.tm_mday);
float eqt = equationOfTime(doy);
float dec = sunDeclination(doy);
float da = diurnalArc(dec, Settings.Latitude);
+2 -2
View File
@@ -94,13 +94,13 @@ static String weekday_str(int wday);
// Get current year.
int year() const
{
return 1970 + tm.tm_year;
return 1900 + tm.tm_year;
}
// Get current month
byte month() const
{
return tm.tm_mon;
return tm.tm_mon + 1; // tm_mon starts at 0
}
// Get current day of the month
+11 -11
View File
@@ -13,7 +13,7 @@
bool isLeapYear(int year) {
return (((1970 + year) > 0) && !((1970 + year) % 4) && (((1970 + year) % 100) || !((1970 + year) % 400)));
return ((year > 0) && !(year % 4) && ((year % 100) || !(year % 400)));
}
/********************************************************************************************\
@@ -25,24 +25,24 @@ uint32_t makeTime(const struct tm& tm) {
// note year argument is offset from 1970 (see macros in time.h to convert to other formats)
// previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9
const uint8_t monthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int i;
uint32_t seconds;
// seconds from 1970 till 1 jan 00:00:00 of the given year
seconds = tm.tm_year * (SECS_PER_DAY * 365);
for (i = 0; i < tm.tm_year; i++) {
// tm_year starts at 1900
uint32_t seconds = 1577836800; // 01/01/2020 @ 12:00am (UTC)
for (int i = 2020; i < (tm.tm_year + 1900); ++i) {
seconds += SECS_PER_DAY * 365;
if (isLeapYear(i)) {
seconds += SECS_PER_DAY; // add extra days for leap years
seconds += SECS_PER_DAY; // add extra days for leap years
}
}
// add days for this year, months start from 1
for (i = 1; i < tm.tm_mon; i++) {
if ((i == 2) && isLeapYear(tm.tm_year)) {
// add days for this year, months start from 0
for (int i = 0; i < tm.tm_mon; i++) {
// Check for February
if ((i == 1) && isLeapYear(tm.tm_year + 1900)) {
seconds += SECS_PER_DAY * 29;
} else {
seconds += SECS_PER_DAY * monthDays[i - 1]; // monthDay array starts from 0
seconds += SECS_PER_DAY * monthDays[i];
}
}
seconds += (tm.tm_mday - 1) * SECS_PER_DAY;
+3 -3
View File
@@ -90,7 +90,7 @@ void ESPEasy_time_zone::logTimeZoneInfo() {
// *----------------------------------------------------------------------*/
uint32_t ESPEasy_time_zone::calcTimeChangeForRule(const TimeChangeRule& r, int yr)
{
uint8_t m = r.month; // temp copies of r.month and r.week
uint8_t m = r.month;
uint8_t w = r.week;
if (w == 0) // is this a "Last week" rule?
@@ -109,8 +109,8 @@ uint32_t ESPEasy_time_zone::calcTimeChangeForRule(const TimeChangeRule& r, int y
tm.tm_min = 0;
tm.tm_sec = 0;
tm.tm_mday = 1;
tm.tm_mon = m;
tm.tm_year = yr - 1970;
tm.tm_mon = m - 1; // TimeChangeRule month starts at 1
tm.tm_year = yr - 1900;
uint32_t t = makeTime(tm);
// add offset from the first of the month to r.dow, and offset for the given week
+2 -2
View File
@@ -161,8 +161,8 @@ bool P082_data_struct::getDateTime(struct tm& dateTime, uint32_t& age, bool& pps
if (!gps->date.isValid() || !gps->time.isValid()) {
return false;
}
dateTime.tm_year = gps->date.year() - 1970;
dateTime.tm_mon = gps->date.month();
dateTime.tm_year = gps->date.year() - 1900;
dateTime.tm_mon = gps->date.month() - 1; // GPS month starts at 1, tm_mon at 0
dateTime.tm_mday = gps->date.day();
dateTime.tm_hour = gps->time.hour();