Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: Decrementing minute messes up the hour

  1. #1

    Decrementing minute messes up the hour

    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);
    }`

  2. #2
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,911
    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

  3. #3
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,911
    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]

  4. #4
    Senior Member
    Join Date
    Aug 2018
    Location
    Brisbane, Australia
    Posts
    159
    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 by thebigg; 01-02-2023 at 01:03 AM. Reason: ninja'd

  5. #5
    Is this a bug or is this just not supposed to be decremented?
    Last edited by PickyBiker; 01-02-2023 at 01:27 AM.

  6. #6
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,911
    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

  7. #7
    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;
      }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •