Timezone Auto DST
#include <timezone.h>
From: https://github.com/JChristensen/Timezone

Itroduction Examples coding Time Change Rules Coding Timezone Objects
Timezone Library Methods toLocal utcIsDst locIsDst
ReadRules writeRules setrules toUtc
Arduino Timezone Library

License

Arduino Timezone Library Copyright (C) 2018 Jack Christensen GNU GPL v3.0

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License v3.0 as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/gpl.html
Note from Paul
I reformat these for my own convenience. 
I don't want to use a lot of disk space so I remove the bloat and add indices.
I also change colors so get more contrast (my eyes don't work as well as they used to).

Introduction

The Timezone library is designed to work in conjunction with the Arduino Time library, which must also be installed on your system. This documentation assumes some familiarity with the Time library.

The primary aim of the Timezone library is to convert Universal Coordinated Time (UTC) to the correct local time, whether it is daylight saving time (a.k.a. summer time) or standard time. The time source could be a GPS receiver, an NTP server, or a Real-Time Clock (RTC) set to UTC. But whether a hardware RTC or other time source is even present is immaterial, since the Time library can function as a software RTC without additional hardware (although its accuracy is dependent on the accuracy of the microcontroller's system clock.)

The Timezone library implements two objects to facilitate time zone conversions:

    A TimeChangeRule object describes when local time changes to daylight (summer) time, or to standard time, for a particular locale.
    A Timezone object uses TimeChangeRules to perform conversions and related functions. It can also write its TimeChangeRules to EEPROM, or read them from EEPROM. Multiple time zones can be represented by defining multiple Timezone objects.

Examples

The following example sketches are included with the Timezone library:
    Clock: A simple self-adjusting clock for a single time zone. TimeChangeRules may be optionally read from EEPROM.
    HardwareRTC: A self-adjusting clock for one time zone using an external real-time clock, either a DS1307 or DS3231 (e.g. Chronodot) which is set to UTC.
    WorldClock: A self-adjusting clock for multiple time zones.
    WriteRules: A sketch to write TimeChangeRules to EEPROM.
    Change_TZ_1: Changes between time zones by modifying the TimeChangeRules.
    Change_TZ_2: Changes between time zones by selecting from an array of Timezone objects.

Coding TimeChangeRules

Normally these will be coded in pairs for a given time zone: One rule to describe when daylight (summer) time starts, and one to describe when standard time starts.

As an example, here in the Eastern US time zone, Eastern Daylight Time (EDT) starts on the 2nd Sunday in March at 02:00 local time. Eastern Standard Time (EST) starts on the 1st Sunday in November at 02:00 local time.

Define a TimeChangeRule as follows:

TimeChangeRule myRule = {abbrev, week, dow, month, hour, offset};
Where:

abbrev: 
	a character string abbreviation for the time zone; it must be no longer
	than five characters.

week: 
	the week of the month that the rule starts.

dow: 
	the day of the week that the rule starts.

hour: 
	the hour in local time that the rule starts (0-23).

offset: 
	the UTC offset in minutes for the time zone being defined.

For convenience, the following symbolic names can be used:

week: First, Second, Third, Fourth, Last
dow: Sun, Mon, Tue, Wed, Thu, Fri, Sat
month: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec

For the Eastern US time zone, the TimeChangeRules could be defined as follows:
	TimeChangeRule usEDT = {"EDT", Second, Sun, Mar, 2, -240};  //UTC - 4 hours
	TimeChangeRule usEST = {"EST", First, Sun, Nov, 2, -300};   //UTC - 5 hours
For Central US:
	TimeChangeRule usCDT = {"CDT", Second, Sun, Mar, 2, -300};  //UTC - 5 hours
	TimeChangeRule usCST = {"CST", First, Sun, Nov, 2, -360};   //UTC - 6 hours

Coding Timezone objects

There are three ways to define Timezone objects.

By first defining TimeChangeRules (as above) and giving the daylight time rule and 
the standard time rule (assuming usEDT and usEST defined as above):
	Timezone usEastern( usEDT, usEST);
or: US Central
	Timezone usCentral( usCDT, usCST);

For a time zone that does not change to daylight/summer time, 
pass a single rule to the constructor. For example:
	Timezone usAZ( usMST, usMST);

By reading rules previously stored in EEPROM. 
This reads both the daylight and standard time rules previously stored at EEPROM address 100:
	Timezone usPacific( 100 );

Note that TimeChangeRules require 12 bytes of storage each, 
so the pair of rules associated with a Timezone object requires 24 bytes total. 
This could possibly change in future versions of the library. 
The size of a TimeChangeRule can be checked with sizeof(usEDT).

Timezone Library Methods

Note that the time_t data type is defined by the Arduino Time library . 
See the Time library documentation here and here for additional details.


/*F******************************************************************** * **********************************************************************/ time_t toLocal( time_t utc ); Description Converts the given UTC time to local time, standard or daylight as appropriate. Syntax myTZ.toLocal(utc); Parameters utc: Universal Coordinated Time (time_t) Returns Local time( time_t ) Exampletime_t eastern, utc; TimeChangeRule usEDT = {"EDT", Second, Sun, Mar, 2, -240}; //UTC - 4 hours TimeChangeRule usEST = {"EST", First, Sun, Nov, 2, -300}; //UTC - 5 hours Timezone usEastern( usEDT, usEST); utc = now(); // CURRENT TIME FROM TIME LIBRARY eastern = usEastern.toLocal( utc );
/*F********************************************************************
*
**********************************************************************/
time_t 
toLocal( time_t utc, TimeChangeRule **tcr);

Description
	As above, converts the given UTC time to local time, and also returns a
	 pointer to the TimeChangeRule that was applied to do the conversion. 
	This could then be used, for example, to include the time zone abbreviation
	 as part of a time display. The caller must take care not to alter the
	 pointed TimeChangeRule, as this will then result in incorrect conversions.

Syntax
	myTZ.toLocal( utc, &tcr );

Parameters
	utc: Universal Coordinated Time (time_t)
	tcr: Address of a pointer to a TimeChangeRule (**TimeChangeRule)

Returns
	Local time (time_t)
	Pointer to TimeChangeRule (**TimeChangeRule)

Example
	time_t eastern, utc;
	TimeChangeRule *tcr;
	TimeChangeRule usEDT = {"EDT", Second, Sun, Mar, 2, -240};  //UTC - 4 hours
	TimeChangeRule usEST = {"EST", First, Sun, Nov, 2, -300};   //UTC - 5 hours
	Timezone usEastern(usEDT, usEST);
	utc = now();	//current time from the Time Library
	eastern = usEastern.toLocal(utc, &tcr);
	Serial.print("The time zone is: ");
	Serial.println(tcr -> abbrev);

/*F********************************************************************
*
**********************************************************************/
bool 
utcIsDST( time_t utc );
bool 
locIsDST( time_t local);

Description
	These functions determine whether a given UTC time or a given local time is
	 within the daylight saving (summer) time interval, and return true or 
	false accordingly.

Syntax
	utcIsDST( utc );
	locIsDST( local );

Parameters
	utc: Universal Coordinated Time (time_t)
	local: Local Time (time_t)

Returns
	true or false (bool)

Example
	if( usEastern.utcIsDST( utc )) 
	{ /*do something*/ }

/*F********************************************************************
*
**********************************************************************/
void 
readRules( int address );
void 
writeRules(int address);

Description
	These functions read or write a Timezone object's two TimeChangeRules from
	 or to EEPROM.

Syntax
	myTZ.readRules( address);
	myTZ.writeRules( address);

Parameters
	address: The beginning EEPROM address to write to or read from (int)

Returns
	None.

Example
	usEastern.writeRules( 100 ); //write rules beginning at EEPROM address 100

/*F******************************************************************** * **********************************************************************/ void setRules( TimeChangeRule dstStart, TimeChangeRule stdStart); Description This function reads or updates the daylight and standard time rules from RAM. Can be used to change TimeChangeRules dynamically while a sketch runs. Syntax myTZ.setRules(dstStart, stdStart); Parameters dstStart: A TimeChangeRule denoting the start of daylight saving (summer) time. stdStart: A TimeChangeRule denoting the start of standard time. Returns None. Example TimeChangeRule EDT = {"EDT", Second, Sun, Mar, 2, -240}; TimeChangeRule EST = {"EST", First, Sun, Nov, 2, -300}; Timezone ET(EDT, EST); ... tz.setRules(EDT, EST);

/*F********************************************************************
*
**********************************************************************/
time_t 
toUTC( time_t local);

Description
	Converts the given local time to UTC time.
	WARNING: This function is provided for completeness, but should seldom be
	 needed and should be used sparingly and carefully.

	Ambiguous situations occur after the Standard-to-DST and the DST-to-Standard
	time transitions. When changing to DST, there is one hour of local time that
	 does not exist, since the clock moves forward one hour. Similarly, when 
	changing to standard time, there is one hour of local time that occurs twice
	 since the clock moves back one hour.

	This function does not test whether it is passed an erroneous time value 
	during the Local-to-DST transition that does not exist. If passed such a 
	time, an incorrect UTC time value will be returned.

	If passed a local time value during the DST-to-Local transition that occurs
	 twice, it will be treated as the earlier time, i.e. the time that occurs 
	before the transition.

	Calling this function with local times during a transition interval should
	 be avoided!

Syntax
	myTZ.toUTC( local );

Parameters
	local: Local Time ( time_t )

Returns
	UTC( time_t )