What is the best library for a mega for local and GMT time

I'm a newbie.
I an wanting to build a module who's job consists of several tasks, but one is to also display both GMT and local time.
After wrestling around with a 1307 RTC and never getting it to work, I finally replaced the unit with a DS3031 RTC which is now successfully wired to my mega 2560 using the DS3231.h library.

My problem is, is that that library doesn't have anything like getGMT/uct in it so i am stuck building a conversion in the sketch that I really don't want to do if there is already a library out there that does the trick. It does have unix time that i may find useful.

Does anyone know of such a library that has GMT?


Why is that conversion so unpleasant to do?
Personally I use GPS time in one application and coded the change between summer time and winter time and it works fine.

The TimeLib library does everything you need, including synchronizing the internal time with an RTC.

To interconvert day/date between local and UTC time, all you need to do is add or subtract the time zone correction in seconds to the unix time stamp that you get from the function now().

Simple example:

#include "TimeLib.h"

tmElements_t te;  //Time elements structure
time_t unixTime; // a time stamp

void setup() {
   // new internal clock setting.
  // convert a date and time into unix time, offset 1970
  te.Second = 0;
  te.Hour = 23; //11 pm
  te.Minute = 0;
  te.Day = 1;
  te.Month = 1;
  te.Year = 2017-1970; //Y2K, in seconds = 946684800UL
  unixTime =  makeTime(te);
  Serial.print("Example 1/1/2017 23:00 unixTime = ");
  setTime(unixTime); //set the current time to the above entered
  Serial.print("now() = ");
  // print as date_time
  // add
  unixTime += 7200UL; //add 2 hours
  Serial.println("After adding 2 hours");
  Serial.print("now() = ");
void print_date_time() { //easy way to print date and time
  char buf[40];
  sprintf(buf, "%02d/%02d/%4d %02d:%02d:%02d", day(), month(), year(), hour(), minute(), second());

void loop() {}

Use the time library that’s built into the compiler:

   Arduino AVR GCC time library demo
// 2020-06-09 improve interface to time.h
// 2020-08-16 remove I/O customizations to make simple

   tm structure shown here because it's hard to find the documentation

  struct tm {
  int8_t          tm_sec; //< seconds after the minute - [ 0 to 59 ]
  int8_t          tm_min; //< minutes after the hour - [ 0 to 59 ]
  int8_t          tm_hour; //< hours since midnight - [ 0 to 23 ]
  int8_t          tm_mday; //< day of the month - [ 1 to 31 ]
  int8_t          tm_wday; //< days since Sunday - [ 0 to 6 ]
  int8_t          tm_mon; //< months since January - [ 0 to 11 ]
  int16_t         tm_year; //< years since 1900
  int16_t         tm_yday; //< days since January 1 - [ 0 to 365 ]
  int16_t         tm_isdst; //< Daylight Saving Time flag

#include <time.h>
#include <locale.h>
#include <util/usa_dst.h> // https://www.nongnu.org/avr-libc/user-manual/usa__dst_8h_source.html

void setup() {
  // time system initialization:
  // required for correct local time
  set_zone(-5 * ONE_HOUR);

  // optional extras
  // location is Toronto
  set_position( 43.741667 * ONE_DEGREE, -79.373333 * ONE_DEGREE);

  Serial.println(F("setting system time to Wednesday, January 1, 2020 12:00:00 AM"));
  set_system_time(1577836800L - UNIX_OFFSET);
  Serial.println(F("press any key to continue..."));
  while (not (Serial.available() > 0));

void loop() {

void printInfo()
  time_t timeNow;
  time_t sunrise;
  time_t sunset;
  time_t solarNoon;
  char sunRiseString[12];
  char sunSetString[12];
  char solarNoonString[12];
  struct tm * timeElements;

  timeNow = time(NULL);
  timeElements = localtime(&timeNow);
  sunrise = sun_rise(&timeNow);
  sunset = sun_set(&timeNow);
  solarNoon = solar_noon(&timeNow);
  strftime(sunRiseString, 12, "%I:%M:%S %p", localtime(&sunrise));
  strftime(sunSetString, 12, "%I:%M:%S %p", localtime(&sunset));
  strftime(solarNoonString, 12, "%I:%M:%S %p", localtime(&solarNoon));

  Serial.print(F("Local time using localtime()/isotime(): "));
  timeElements = localtime(&timeNow);
  //show local time
  Serial.print(F("Local time using time()/ctime(): "));
  timeNow = time(NULL);

  Serial.print(F("Daylight Savings Time "));
  Serial.print(timeElements->tm_isdst ? "is" : "is not");
  Serial.println(F(" in effect."));

  Serial.print(F("Sun rises at: "));

  Serial.print(F("Sun sets at: "));

  Serial.print(F("Solar noon is at: "));

  Serial.print(F("Solar declination: "));

  Serial.print(F("Day "));
  Serial.print(" of ");
  Serial.println(timeElements->tm_year + 1900);

  Serial.print(F("Week "));
  Serial.print(week_of_year(timeElements, SUNDAY));
  Serial.print(F(" of "));
  Serial.println(timeElements->tm_year + 1900);

  Serial.print(F("Week "));
  Serial.print(week_of_month(timeElements, SUNDAY));
  Serial.println(" of the month");

  Serial.print(F("Days in this month: "));
  Serial.println(month_length(timeElements->tm_year, timeElements->tm_mon + 1));

  Serial.print(F("This year "));
  Serial.print(is_leap_year(timeElements->tm_year) ? "is" : "is not");
  Serial.println(F(" a leap year."));

  Serial.print(F("moon phase: "));

void printWelcome()
  Serial.print(F("\n\nWelcome, testing the AVR GCC time library\n"));

   System timer tick uses micros() for timing
void tickUpdate() {
  static unsigned long lastTickTime;
  static int syncIntervalCount = 0;
  if (micros() - lastTickTime >= 1000000) {
    lastTickTime += 1000000;

void printTime() {
  time_t timeNow;
  struct tm * timeElements;
  //show UTC time in ISO (also Canadian :=)
  timeNow = time(NULL);
  timeElements = gmtime(&timeNow);

Why is that conversion so unpleasant to do?
Personally I use GPS time in one application and coded the change between summer time and winter time and it works fine.

Remember, I'm a newbie.
Mainly want it because I figure library code is compiled thinner than sketch code and probably runs faster too. Maybe I am wrong about thinner or faster, but it also gets it out of the way.
I just want that type of code hidden in the library where all i do is use it, let the code in the sketch pertain to the functions I want the unit to do rather than adding in a bunch of low level utility code.
I will have several state machines involved to emulate multitasking and i figure having that GMT code and stuff like that in the low level library just keeps the code cleaner and less for me to have to mess with and troubleshoot.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.