#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
const uint8_t NUM_BTNS = 3;
const uint8_t BTN_PINS[] = {4, 5, 6};
const uint8_t MODE_PIN = 7;
const uint32_t ONE_SEC = 1000;
typedef enum { STATE_INIT,
               STATE_RUN,
               STATE_SET_YEAR,
               STATE_SET_MONTH,
               STATE_SET_DATE,
               STATE_SET_HOUR,
               STATE_SET_MINUTE,
               STATE_SET_SECOND
             } states;
// set initial state
states state = STATE_INIT;
states oldState = state;
states nextState = STATE_RUN;
uint8_t btnState[NUM_BTNS];
uint8_t oldBtnState[NUM_BTNS];
uint32_t lastTime = 0;
char daysOfTheWeek[7][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
bool setMode = false;
LiquidCrystal_I2C lcd(0x27, 16, 2);
RTC_DS1307 rtc;
int checkButtons()  {
  int btnNumber = 0;
  for (int i = 0; i < NUM_BTNS; i++) {
    // check each button
    btnState[i] = digitalRead(BTN_PINS[i]);
    if (btnState[i] != oldBtnState[i])  { // if it changed
      oldBtnState[i] = btnState[i];       // remember state for next time
      //btnNumber = i + 1;
      //Serial.print("Button ");
      //Serial.print(btnNumber);
      if (btnState[i] == LOW)  {          // was just pressed
        btnNumber = i + 1;
        //Serial.println(" pressed.");
      } else {
        btnNumber = -1;                   // was just released
        //Serial.println(" released.");
      }
      delay(20);  // debounce
    }
  }
  return btnNumber;
}
void showSplash() {
  Serial.println("RTC clock");
  lcd.setCursor(3, 0);
  lcd.print("RTC Clock");
  lcd.setCursor(3, 1);
  lcd.print("Demo V1.0");
  delay(2000);
  lcd.clear();
}
void updateDisplay(bool mode, bool doSerial)  {
  DateTime now = rtc.now();
  char dateBuff[16];
  char timeBuff[16];
  if (doSerial) {
    char printBuff[32];
    snprintf(printBuff, 32, "%s %2d/%2d/%4d %2d:%02d:%02d",
             daysOfTheWeek[now.dayOfTheWeek()],
             now.month(),
             now.day(),
             now.year(),
             now.hour(),
             now.minute(),
             now.second()
            );
    Serial.println(printBuff);
  }
  snprintf(dateBuff, 16, "%s %2d/%2d/%4d",
           daysOfTheWeek[now.dayOfTheWeek()],
           now.month(),
           now.day(),
           now.year()
          );
  snprintf(timeBuff, 16, " %2d:%02d:%02d %s",
           mode ? now.hour() : now.twelveHour(),
           now.minute(),
           now.second(),
           mode ? "  " : (now.isPM() ? "PM" : "AM")
          );
  lcd.setCursor(1, 0);
  lcd.print(dateBuff);
  if (mode) {
    lcd.setCursor(3, 1);
  } else {
    lcd.setCursor(2, 1);
  }
  lcd.print(timeBuff);
}
void setup () {
  Serial.begin(115200);
  lcd.init();
  lcd.backlight();
  if (!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    lcd.print("RTC not found!");
    for (;;); // don't proceed
  }
  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // You would typically set the time here, e.g., RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  for (int i = 0; i < NUM_BTNS; i++) {
    pinMode(BTN_PINS[i], INPUT_PULLUP);
  }
  pinMode(MODE_PIN, INPUT_PULLUP);
  showSplash();
}
void loop() {
  bool mode = digitalRead(MODE_PIN); // 24h is HIGH
  int buttonNum = checkButtons();
  if (buttonNum > 0) {
    Serial.print("Button ");
    if (buttonNum == 1) {
      Serial.print("INC");
    } else if (buttonNum == 2)  {
      Serial.print("DEC");
    } else if (buttonNum == 3)  {
      setMode = true;
      Serial.print("SET");
    }
    Serial.println(" pressed.");
  }
  if (setMode)  {
    // advance state machine
    //lcd.clear();
    //lcd.print("Set Mode");
  }
  if (millis() - lastTime >= ONE_SEC) {
    lastTime = millis();
    updateDisplay(mode, false);
  }
}
12h / 24h
Inc
Dec
Set