Help with GMT offset incriment/decriment button

Hello,

I am programming a real time clock (using Arduino Uno, DS1307, LCD 16x2)
Have done the following:

  • LCD shows 2 rows - upper row is YY/MM/DD, lower row is hh/mm/ss GMT-0
  • 24 hour format
  • Three additional buttons - one cycles through upper and lower row values, second one increases the value of the active selection and the third one decreases the value of the active selection.

All I need right now is to make two more buttons that change the GMT offset from min to max value. Additionally, year, month, day and hour must change according to the offset and the default value is GMT-0.

//************Libraries**************//
#include <Wire.h>
#include <RTClib.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20,16,2);     // 0x3f if real, 0x20 if simulation environment
RTC_DS1307 RTC;

//************Buttons*****************//
int P1=6; // Set menu
int P2=7; // Set menu +
int P3=8; // Set menu -
int P4=4; // GMT offset -
int P5=5; // GMT offset +

//************Variables**************//
int hourup;
int minup;
int yearup;
int monthup;
int dayup;
int menu=0;

void setup()
{
  lcd.begin();                        // starts LCD
  lcd.backlight();                    // activates the backlight of the LCD
  lcd.clear();                        // clears LCD
  Serial.begin(9600);                 // start the serial connection to the PC.
  pinMode(P1,INPUT);                  // setting pin1 as input
  pinMode(P2,INPUT);                  // setting pin2 as input
  pinMode(P3,INPUT);                  // setting pin3 as input
  pinMode(P4,INPUT);                  // setting pin4 as input
  pinMode(P5,INPUT);                  // setting pin5 as input
  Wire.begin();
  RTC.begin();
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // Set the date and time at compile time
    // RTC.adjust(DateTime(__DATE__, __TIME__));
  }
    // RTC.adjust(DateTime(__DATE__, __TIME__));
    // The default display shows the date and time
     RTC.adjust(DateTime(2019, 12, 10, 15, 49, 0));
}

//************Menu index increase if Set button is pressed**************//
void loop()
{ 
  if(digitalRead(P1))
  {
   menu=menu+1;         // If P1 button is pressed, goes to the other menu
  }
  if (menu==0)          // Main menu that shows date
    {
     DisplayDateTime(); // void DisplayDateTime()
    }
  if (menu==1)          // Menu that allows to set the hour
    {
    DisplaySetHour();   // void DisplaySetHour()
    }
  if (menu==2)          // Menu that allows to set the minute
    {
    DisplaySetMinute(); // void DisplaySetMinute()
    }
  if (menu==3)          // Menu that allows to set the year
    {
    DisplaySetYear();   // void DisplaySetYear()
    }
  if (menu==4)          // Menu that allows to set the month
    {
    DisplaySetMonth();  // void DisplaySetMonth()
    }
  if (menu==5)          // Menu that allows to set the day
    {
    DisplaySetDay();    // void DisplaySetDay()
    }
  if (menu==6)          
    {
    DisplaySetDay();    // void DisplaySetDay()
    }    
  if (menu==7)
    {
    StoreAgg(); 
    delay(500);
    menu=0;
    }
    delay(100);
}

//************Displays current date and time**************//
void DisplayDateTime ()
{
  DateTime now = RTC.now();
  lcd.setCursor(0, 1);            // sets cursor on the second line of the LCD
  if (now.hour()<=9)              // if the hour reaches more than 10, 0 will not be printed in front (01, 02, ... , 08, 09)
  {
    lcd.print("0");
  }
  lcd.print(now.hour(), DEC);     // prints hours in decimals (DEC)
  hourup=now.hour();              // sets variable to current hour that is set
  lcd.print(":");
  if (now.minute()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.minute(), DEC);
  minup=now.minute();
  lcd.print(":");
  if (now.second()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.second(), DEC);
  lcd.print(" GMT-0");
  lcd.setCursor(0, 0);
  if (now.year()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.year(), DEC);
  yearup=now.year();
  lcd.print("/");
  if (now.month()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.month(), DEC);
  monthup=now.month();
  lcd.print("/");
  if (now.day()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.day(), DEC);
  dayup=now.day();
}

//************Setting hours**************//
void DisplaySetHour()
{
  lcd.clear();
  DateTime now = RTC.now();
  if(digitalRead(P2)==HIGH)    // if button 2 is pressed, do the following:
  {
    if(hourup==23)             // so that overflow would not occur, if hours are more than 23, sets it back to 0 in the next line
    {
      hourup=0;
    }
    else
    {
      hourup++;                // if no overflow is occuring, adds 1 to hours
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if(hourup==0)
    {
      hourup=23;
    }
    else
    {
      hourup--;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set hour:");
  lcd.setCursor(0,1);
  lcd.print(hourup,DEC);
  delay(200);
}

//************Setting minutes**************//
void DisplaySetMinute()
{
  lcd.clear();
  DateTime now = RTC.now();
  if(digitalRead(P2)==HIGH)
  {
    if (minup==59)
    {
      minup=0;
    }
    else
    {
      minup++;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if (minup==0)
    {
      minup=59;
    }
    else
    {
      minup--;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set minutes:");
  lcd.setCursor(0,1);
  lcd.print(minup,DEC);
  delay(200);
}

//************Setting the year**************//
void DisplaySetYear()
{
  lcd.clear();
  DateTime now = RTC.now();
  if(digitalRead(P2)==HIGH)
  {  
    if (yearup==2099)
    {
      yearup=2000;
    }
    else
    {  
    yearup++;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if (yearup==2000)
    {
      yearup=2099;
    }
    else
    {
    yearup--;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set year:");
  lcd.setCursor(0,1);
  lcd.print(yearup,DEC);
  delay(200);
}

//************Setting the month**************//
void DisplaySetMonth()
{
  lcd.clear();
  DateTime now = RTC.now();
  if(digitalRead(P2)==HIGH)
  {
    if (monthup==12)
    {
      monthup=1;
    }
    else
    {
      monthup++;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if (monthup==1)
    {
      monthup=12;
    }
    else
    {
      monthup--;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set month:");
  lcd.setCursor(0,1);
  lcd.print(monthup,DEC);
  delay(200);
}

//************Setting the day**************//
void DisplaySetDay()
{
  lcd.clear();
  if(digitalRead(P2)==HIGH)
  {
    if (dayup==31)
    {
      dayup=1;
    }
    else
    {
      dayup++;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if (dayup==1)
    {
      dayup=31;
    }
    else
    {
      dayup--;
    }
  }
  lcd.setCursor(0,0);
  lcd.print("Set day:");
  lcd.setCursor(0,1);
  lcd.print(dayup,DEC);
  delay(200);
}

//************Saving variables**************//
void StoreAgg()
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("CURRENTLY SAVING");
  lcd.setCursor(0,1);
  lcd.print("PLEASE WAIT");
  RTC.adjust(DateTime(yearup,monthup,dayup,hourup,minup,0));
  delay(500);
  lcd.clear();
}

Any help is appreciated.

I would recommend using unix time (seconds since Jan 1st 1970) for time calculation. Then you do not need to care about any overflows.

Just add/subtract 60 seconds minutes or add/subtract 3600 seconds for an hour and so on. For displaying you extract hour, minutes and so on from the class.

Depending on the time library you can get unix time slightly different.

I’d get a ds3231, 1307’s drift a lot

+1 for DS3231 (instead of DS1307) and use of TimeLib.h for time adjustments. The DS3231 should be initialized to Universal Coordinated Time.

To convert from UTC to local time, just add or subtract 3600 seconds per hour (as appropriate) to the UTC Unix timestamp.