How do you get your time zone from GPS?

Hi all,

I’ve done extensive searching and while I see the question has been asked before and never solved, I believe I’ve found a possible solution that hasn’t been addressed before…so here goes:

I’ve got a ublox Neo-6m gps module attached to my uno, running the “tinygps++” library and all is great (I can get lat,long, etc) using the library requests like:

Serial.print(gps.altitude.meters());

The problem is I would like to display the current time depending on my timezone, and the tinygps++ library doesn’t seem to be able to tell me what time zone I’m in.

But there appears to be the NMEA string $GPZDA or $PMTK314 (I’m getting a bit confused by the strings so I think it’s both) that contains the offset of the time in my position relative to UST.

I must admit that I don’t really understand how to do parsing of data so I’m hoping that someone very kind here can help me. I also hope I’ve provided enough info to enable quick and easy help. :slight_smile:

Here is a website that shows the contents of the GPZDA string: Arduino GPS clock using NMEA protocol | electronicsblog.net

And here is a website that details someone getting the date and time from the required NMEA string
http://bodgitandscarper.co.uk/category/arduino/
They also kindly link to their sketch on github, but after downloading it and trying to modify it for my use, it just left me terribly confused.

Just to confirm, I’m only asking how to get the two offsets (local zone hour and local zone minutes) into a memory location that I can use.

And for the purposes of my sketch, this is the code I’m using for testing:

#include <TinyGPS++.h>
#include <SoftwareSerial.h>
/*
   This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
   It requires the use of SoftwareSerial, and assumes that you have a
   4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx).
*/
static const int RXPin = 4, TXPin = 3;
static const uint32_t GPSBaud = 4800;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);

void setup()
{
  Serial.begin(115200);
  ss.begin(GPSBaud);

  Serial.println(F("DeviceExample.ino"));
  Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
  Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
  Serial.println(F("by Mikal Hart"));
  Serial.println();
}

void loop()
{
  // This sketch displays information every time a new sentence is correctly encoded.
  while (ss.available() > 0)
    if (gps.encode(ss.read()))
      displayInfo();

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while(true);
  }
}

void displayInfo()
{
  Serial.print(F("Location: ")); 
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F("  Date/Time: "));
  if (gps.date.isValid())
  {
    Serial.print(gps.date.month());
    Serial.print(F("/"));
    Serial.print(gps.date.day());
    Serial.print(F("/"));
    Serial.print(gps.date.year());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.print(F(" "));
  if (gps.time.isValid())
  {
    if (gps.time.hour() < 10) Serial.print(F("0"));
    Serial.print(gps.time.hour());
    Serial.print(F(":"));
    if (gps.time.minute() < 10) Serial.print(F("0"));
    Serial.print(gps.time.minute());
    Serial.print(F(":"));
    if (gps.time.second() < 10) Serial.print(F("0"));
    Serial.print(gps.time.second());
    Serial.print(F("."));
    if (gps.time.centisecond() < 10) Serial.print(F("0"));
    Serial.print(gps.time.centisecond());
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();
}

If anyone can help it’s greatly appreciated, and if you can keep it relatively simple then it might help me understand :slight_smile:

The time broadcast by the gps system is universal time.

Your local time zone, depends on where you are.

It would be possible, although not very practical, to create a database of the boundaries of all the time zones. Your gps device could then calculate its location, determine what time zone region it is in, get the univeral time from the gps signal, and then calculate the local time.

It would be possible, although not very practical, to create a database of the boundaries of all the time zones

Every linux distribution I know of has and uses exactly such a database (tzdata), and it is updated very frequently! Learn more about this international effort here: https://en.wikipedia.org/wiki/Tz_database

michinyon: The time broadcast by the gps system is universal time.

Your local time zone, depends on where you are.

Are you certain that those two offsets don't contain the data for how far off UTC your current location time is? If not, what are they for?

The satellites certainly can't give you any information about your time zone, because they don't know where you are.

However, some GPS modules can in principle give you that information via the $GPZDA message, if they are programmed to find the time zone corresponding to the module's current location. The necessary information is in the tzdata database.

As stated before, the GPS system transmits UTC only. You have to implement the correction to your local time zone.