New (BETA) library to configure local time settings

I have just published a new library named TzCfg that has the features listed below. You are invited to participate in the beta.
Documentation is available on GitHub: https://github.com/rwpalmer/TzCfg

TzCfg

Configures local time based on:
  • A device’s IP address
  • GPS coordinates
  • A specified time zone ID like “America/Chicago”
Automatically performs DST transitions at their scheduled time
Obtains time zone data from the web
  • Connects to timezonedb.com to get timezone data based on the time zone ID or GPS coordinates. This requires an API-key. A free API-key provides a service level up to 1 transaction per second. A fee is charged for service above this level. (Click the link for more details).

  • Connects to ipapi.com to lookup a device’s “return IP address” and the associated time zone. This site does not require an API key for non-commercial use, up to 150 tranactions per minute. Commercial access requires prior approval. (Click the link for more details)

  • Usage Details: The library queries timezonedb twice each time it performs a timezone query. The library queries ip-api once each time a timezone query is performed based on IP address. The library performs a timezone query when the device boots, and then approximately once every three weeks while it is running. In other words, “The free API-keys will go a long way”.

Requires128 bytes EEPROM storage
  • So the device can store timezone data between boots and can set time properly when the device boots without network connectivity.
  • uses EEPROM bytes 0 to 127 by default, but the location is configurable.

Typical Usage:

    #include "TzCfg.h"

    TzCfg tzCfg;

    void Setup() {
        tzCfg.begin();
        tzCfg.setEepromStartByte(0);
        TzCfg.setApiKey_timezonedb((char*)“YOUR_TIMEZONEDB_API_KEY”);

        // And ONE of the following setTimezoneBy statements.
        tzCfg.setTimezoneByID((char*)"America/Chicago");
        tzCfg.setTimezoneByGPS(46.786671, -92.100487);
        tzCfg.setTimezoneByIP();
    }

    void Loop() {
        tzCfg.maintainLocalTime();
    }

7 Likes

Nice work!

Thank you. I appreciate the feedback.

I’d like to know three things if you don’t mind:

  1. What device type did you run it on?
  2. What is your timezone?
  3. What lookup method did you use?

Please let me know if you have an issues, suggestions, or other comments.

Have not tried it yet but I am working on something a product that will will need this.

Both IP and GPS lookup will be beneficial since some units will have GPS receivers built in.

I’ll try to test this soon and report back.

Many other people post about how to best handle the time and time zone issues so this should help others also.

Just tried example 1 Get Time Zone From IP Address on a P1 Redboard and it worked just fine.

So now this is stored in EEPROM, I need to look into the docs more.

I also tried Example 3 and it worked also:

I then changed the time zone via the web function successfully.

Very useful library :+1: @Bear

1 Like

Would this be compatible with a Core? :slight_smile:

@daneboomer, yes, the Core supports emulated EEPROM. However, as per the documentation:

The Core has 127 bytes of emulated EEPROM.

ah. So a byte short. Thanks. I did look at the docs but was concerned about the word emulated. Hadn’t spotted the byte deficiency. I’m wondering about installing the code on a Photon and having my Cores poll the Photon periodically for “is DST?” maybe once a week.
It’s such a shame Particle won’t handle DST for its users - seems like such an easy win which would benefit so many.

@daneboomer, I believe there are examples in the forum that use IP location services to establish local time and DST. Webhooks are used. Do a search!

Another? :wink: Sure! Happy to! :slight_smile:

EDIT: So I've found this thread which is probably the one you mean (found a much older one too). I don't think I have space on my Cores to use that library, unfortunately. Thanks for the heads up as if I ever make an IoT clock or similar I'd definitely consider it. For now, it's a bit too much overhead.

1 Like

You may not need to.

You have a similar question in another thread where you already found my implementation which works for Europe.

Double-posting is rarely helpful - reasoning behind that statement can be found here

Thanks again @ScruffR. In my defence, (I think solely because of my use of the Timealarms library? I couldn’t get your code to work) I was in a bit of a rush to try to get a fix implemented asap. In the end I’ve gone for @BulldogLowell’s code which I’m using like this (in case it helps anyone coming after me):

bool isDST(int day, int month, int dayOfWeek)
{
  if (month < 3 || month > 10)
  {
    return false;
  }
  if (month > 3 && month < 10)
  {
    return true;
  }
  int previousSunday = day - dayOfWeek;
  if (month == 3)
  {
    return previousSunday >= 25;
  }
  if (month == 10) return previousSunday < 25;
  {
    return false;
  }
}

and in loop

bool daylightSavings = isDST(Time.day(), Time.month(), Time.weekday());
Time.zone(daylightSavings? 1 : 0);

Seems to be working at the moment.

If you could send me a SHARE THIS REVISION link I can have a look at the reason for your build troubles and maybe find a solution.