Timezone World Clock
#include <Timezone.h>


/*F********************************************************************
* Arduino Timezone Library Copyright (C) 2018 by Jack Christensen and
licensed under GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
Arduino Timezone Library example sketch.
Self-adjusting clock for multiple time zones.
Jack Christensen Mar 2012
For time zone information: http://www.timeanddate.com/worldclock/
**********************************************************************/
#include <Timezone.h>    // https://github.com/JChristensen/Timezone

//************************* DEFINES ************************************

//************************* PROTOTYPES ************************************

//************************* VARIABLES ************************************
// Australia Eastern Time Zone (Sydney, Melbourne)
TimeChangeRule aEDT = {"AEDT", First, Sun, Oct, 2, 660};    // UTC + 11 hours
TimeChangeRule aEST = {"AEST", First, Sun, Apr, 3, 600};    // UTC + 10 hours
Timezone ausET(aEDT, aEST);
// Moscow Standard Time (MSK, does not observe DST)
TimeChangeRule msk = {"MSK", Last, Sun, Mar, 1, 180};
Timezone tzMSK(msk);
// Central European Time (Frankfurt, Paris)
TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120};     // Central European Summer Time
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60};       // Central European Standard Time
Timezone CE(CEST, CET);
// United Kingdom (London, Belfast)
TimeChangeRule BST = {"BST", Last, Sun, Mar, 1, 60};        // British Summer Time
TimeChangeRule GMT = {"GMT", Last, Sun, Oct, 2, 0};         // Standard Time
Timezone UK(BST, GMT);
// UTC
TimeChangeRule utcRule = {"UTC", Last, Sun, Mar, 1, 0};     // UTC
Timezone UTC(utcRule);
// US Eastern Time Zone (New York, Detroit)
TimeChangeRule usEDT = {"EDT", Second, Sun, Mar, 2, -240};  // Eastern Daylight Time = UTC - 4 hours
TimeChangeRule usEST = {"EST", First, Sun, Nov, 2, -300};   // Eastern Standard Time = UTC - 5 hours
Timezone usET(usEDT, usEST);
// US Central Time Zone (Chicago, Houston)
TimeChangeRule usCDT = {"CDT", Second, Sun, Mar, 2, -300};
TimeChangeRule usCST = {"CST", First, Sun, Nov, 2, -360};
Timezone usCT(usCDT, usCST);
// US Mountain Time Zone (Denver, Salt Lake City)
TimeChangeRule usMDT = {"MDT", Second, Sun, Mar, 2, -360};
TimeChangeRule usMST = {"MST", First, Sun, Nov, 2, -420};
Timezone usMT(usMDT, usMST);
// Arizona is US Mountain Time Zone but does not use DST
Timezone usAZ(usMST);
// US Pacific Time Zone (Las Vegas, Los Angeles)
TimeChangeRule usPDT = {"PDT", Second, Sun, Mar, 2, -420};
TimeChangeRule usPST = {"PST", First, Sun, Nov, 2, -480};
Timezone usPT(usPDT, usPST);
/*F********************************************************************
*
**********************************************************************/
void 
setup()
{
	Serial.begin( BAUD );
	// set system time to UTC
	// warning: assumes that compileTime() returns US EDT
	// adjust the following line accordingly if you're in another time zone
	setTime( compileTime() + 240 * 60 );
}
/*F********************************************************************
*
**********************************************************************/
void 
loop()
{
	time_t utc = now( );
	Serial.println( );
	printDateTime( ausET, utc, "Sydney");
	printDateTime( tzMSK, utc, " Moscow");
	printDateTime( CE, utc, "Paris");
	printDateTime( UK, utc, " London");
	printDateTime( UTC, utc, " Universal Coordinated Time");
	printDateTime( usET, utc, " New York");
	printDateTime( usCT, utc, " Chicago");
	printDateTime( usMT, utc, " Denver");
	printDateTime( usAZ, utc, " Phoenix");
	printDateTime( usPT, utc, " Los Angeles");
	delay( 10000 );
}
/*F********************************************************************
* Function to return the compile date and time as a time_t value
**********************************************************************/
time_t 
compileTime()
{
	const time_t FUDGE( 10);     // fudge factor to allow for compile time ( seconds, YMMV)
	const char *compDate = __DATE__, *compTime = __TIME__, *months = "JanFebMarAprMayJunJulAugSepOctNovDec";
	char chMon[4], *m;
	tmElements_t tm;
	strncpy( chMon, compDate, 3);
	chMon[3] = '\0';
	m = strstr( months, chMon);
	tm.Month = ( ( m - months) / 3 + 1);
	tm.Day = atoi( compDate + 4);
	tm.Year = atoi( compDate + 7) - 1970;
	tm.Hour = atoi( compTime);
	tm.Minute = atoi( compTime + 3);
	tm.Second = atoi( compTime + 6);
	time_t t = makeTime( tm);
	return t + FUDGE;           // add fudge factor to allow for compile time
}
/*F********************************************************************
* given a Timezone object, UTC and a string description, convert and print local time with time zone
**********************************************************************/
void 
printDateTime( Timezone tz, time_t utc, const char *descr)
{
	char buf[40];
	char m[4];    // temporary storage for month string ( DateStrings.cpp uses shared buffer)
	TimeChangeRule *tcr;        // pointer to the time change rule, use to get the TZ abbrev
	time_t t = tz.toLocal( utc, &tcr);
	strcpy( m, monthShortStr( month( t)));
	sprintf( buf, "%.2d:%.2d:%.2d %s %.2d %s %d %s",
	hour( t), minute( t), second( t), dayShortStr( weekday( t)), day( t), m, year( t), tcr -> abbrev);
	Serial.print( buf);
	Serial.print( ' ');
	Serial.println( descr);
}