Decrementing minute messes up the hour

PickyBiker

Well-known member
In the following sketch when the minute is decremented past zero, the hour is decrementing by 4 instead of 1, and the minute goes to 15 instead of 59.
The same decrementing is applied to the day, but in that case the month decrements correctly.

What am I doing wrong?

`#include <TimeLib.h>
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
delay(250);
Serial.println();
setTime(5, 5, 0, 5, 5, 2021);
}

void loop()
{
// put your main code here, to run repeatedly:
digitalClockDisplay();
delay(100);
}

void digitalClockDisplay()
{
// digital clock display of the time
setTime(hour(), minute()-1, second(), day()-1, month(), year());
Serial.print(hour());
printDigits(minute());
// printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
// Serial.print(year());
Serial.println();
}

void printDigits(int digits) {
// utility function for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if (digits < 10)
Serial.print('0');
Serial.print(digits);
}`
 
The problem is, as you say, caused when the value of minute() is zero and you therefore pass minus one as the value for the minute. I haven't figured out yet why that blows up the time library.

Pete
 
AHA. settime stores its arguments in a tmElements_t structure and then calls maketime() to convert that structure to a time_t (number of seconds).
BUT, all the elements of a tmElements_t structure are declared to be uint8_t which means that the -1 you passed as the minutes is convert to +255. This is then multiplied by 60 to convert the minutes to seconds and then added to the current accumulated value.
So instead of subtracting 60 seconds from the time, it adds 255 minutes = 4 hours and 15 minutes.

So, you'll have to handle negative values yourself before they are passed to settime().


Pete
[edited to fix a computational error]
 
I suspect that the problem arises because the Minute field of tmElements (actually all the fields) is a uint8_t and -1 gets cast to 255. 60 * 4 = 240 which explains the 4 hour jump in Hour

Edit: ninja'd
 
Last edited:
It is expecting you to pass a valid date and time . If you want to do arithmetic on the date, you have to do it yourself and make sure that the result is valid before passing it to settime. The best way to do this is to first convert the (valid) starting date/time to a time_t value using the maketime function. You can then add or subtract any number of seconds from that and then, if/when required, convert it back to a date/time using the breaktime function.

Pete
 
This seems to work okay.
Code:
    case mnDn:
      if (minute() > 0)
    setTime(hour(), minute() - 1, second(), day(), month(), year());
  else if (hour() > 0)
    setTime(hour() - 1, 59, second(), day(), month(), year());
  else
    setTime(23, 59, second(), day(), month(), year());
      break;
  }
 
Back
Top