Introduction: Adjusting GPS Date and Time to Your Time Zone

About: Electronic hobbyist with an interest in programming and making stuff work.

I may be completely wrong by putting up this Instructables but I have struggled to find an easy way to correct GPS time and date data to my time zone here in Australia. I have made a few Arduino projects that have included a GPS module with some form of data logging. Each time I have had difficulties converting UTC time captured from the NMEA data string to local time or have simply gave up and used a RTC in my project.

There are a few solutions on the web include a couple here on Instructables but as a amateur coder I have struggled to integrate the code into my own sketches.

Hopefully this posting will give those equally struggling, an easy solution. I've tried to keep the code as simple as possible with plenty of options to suit your setup, Uno or Mega, software and hardware serial connections. I've also put the time zone calculation in a simple function that can be copied and pasted straight into your own sketch.

You'll need to install the TinyGPS++ Library and the AltSoftSerial Library for the sketch to compile correctly. I have had better compatibility with the GPS modules I have by using the TinyGPS++ library. The AltSoftSerial Library makes it easier to have multiple serial device connected to your Uno. This isn't a problem when using a Mega but if you do want to attach your serial devices on different digital pins, this is the easiest library I have found.

Here is the sketch below :

#include <Time.h>             // Time Library
#include <TinyGPS++.h>        // GPS Library
#include <AltSoftSerial.h>    // Allows two Serial connections

// Set GPS RX and TX pins if using software serial connections.
// See below to use hardware serial connections

//static const int RXPin = 4, TXPin = 3;  // Example Uno
static const int RXPin = 48, TXPin = 46;  // Example Mega

static const uint32_t GPSBaud = 4800;       
//static const uint32_t GPSBaud = 9600;     

// The TinyGPS++ object
TinyGPSPlus gps;

// Serial connection to the GPS device
AltSoftSerial Serial_GPS;
//#define Serial_GPS Serial1  // Uncomment this line & comment
                              // above line to use a hardware
                              // Serial Port

// Change this value to suit your Time Zone
const int UTC_offset = 10;   // Eastern Australia Time

time_t prevDisplay = 0; // Count for when time last displayed

void setup()
{
  Serial.begin(9600);
  Serial_GPS.begin(GPSBaud); // Start GPS Serial Connection
  
  Serial.println("Waiting for GPS time ... ");
}

void loop()
{
  GPS_Timezone_Adjust();  // Call Time Adjust Function
}

void GPS_Timezone_Adjust(){
  
  while (Serial_GPS.available()) {
    if (gps.encode(Serial_GPS.read())) { 
      
      int Year = gps.date.year();
      byte Month = gps.date.month();
      byte Day = gps.date.day();
      byte Hour = gps.time.hour();
      byte Minute = gps.time.minute();
      byte Second = gps.time.second();

        // Set Time from GPS data string
        setTime(Hour, Minute, Second, Day, Month, Year);
        // Calc current Time Zone time by offset value
        adjustTime(UTC_offset * SECS_PER_HOUR);           
      
    }
  }
  
  // -- Delete this section if not displaying time ------- //
  if (timeStatus()!= timeNotSet) {
    if (now() != prevDisplay) {     
      prevDisplay = now();
      SerialClockDisplay();
    }
  }
  // -- Also delete the SerialClockDisplay()function ---- //
  
} // Keep

void SerialClockDisplay(){
  // Serial Monitor display of new calculated time - 
  // once adjusted GPS time stored in now() Time Library 
  // calculations or displays can be made.
  
  if (hour() < 10) Serial.print(F("0"));
        Serial.print(hour());
        Serial.print(F(":"));
  if (minute() < 10) Serial.print(F("0"));
        Serial.print(minute());
        Serial.print(F(":"));
  if (second() < 10) Serial.print(F("0"));
        Serial.print(second()); 
        
        Serial.print(" ");
  
  if (day() < 10) Serial.print(F("0"));      
        Serial.print(day());
        Serial.print(F("/"));
  if (month() < 10) Serial.print(F("0"));
        Serial.print(month());
        Serial.print(F("/"));
        Serial.println(year());
}

I hope you've found this useful and it makes your next GPS datalogging project a lot easier.