Giter Site home page Giter Site logo

jchristensen / timezone Goto Github PK

View Code? Open in Web Editor NEW
260.0 23.0 97.0 69 KB

Arduino library to facilitate time zone conversions and automatic daylight saving (summer) time adjustments.

License: GNU General Public License v3.0

C++ 100.00%
arduino-library timezone time arduino

timezone's Introduction

Arduino Timezone Library

https://github.com/JChristensen/Timezone
README file
Jack Christensen
Mar 2012

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

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 is a character string abbreviation for the time zone; it must be no longer than five characters.

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

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

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

offset is 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

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);

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 <TimeLib.h>. See the Time library documentation here and here for additional details.

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)

Example
time_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 the Time Library
eastern = usEastern.toLocal(utc);

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);

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*/ }

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

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);

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)

timezone's People

Contributors

jchristensen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

timezone's Issues

Issues from blog

Found a couple of issues with the Timezone library:

  1. In calcTimeChanges()
  • The following doesn't look right.
    m_dstUTC = m_dstLoc - m_std.offset * SECS_PER_MIN;
    m_stdUTC = m_stdLoc - m_dst.offset * SECS_PER_MIN;
  • Should it be:
    m_dstUTC = m_dstLoc - m_dst.offset * SECS_PER_MIN;
    m_stdUTC = m_stdLoc - m_std.offset * SECS_PER_MIN;
  1. Initialization of the following member variables missing in the constructor.
   m_dstUTC = 0; 
   m_stdUTC = 0;
   m_dstLoc = 0;
   m_stdLoc = 0;
  • The new operator may not necessarily zeros the member variables (implementation dependent). This causes the utcIsDST() method to return false, resulting in the daylight saving not working properly.

BUG: Time time displayed for UTC+08:00 timezone (MYT) is 1 hour in future

I am trying to use this library to display time for my timezone which is UTC+8 but it appears the time obtained after conversion is 1 hour in the future.

Expected result:
Wednesday, 03/09/2019 04:46:40

Actual result:
Wednesday, 03/09/2019 05:46:40

The code I am running is this:

// vim: autoindent smartindent syntax=c expandtab tabstop=4 shiftwidth=4 softtabstop=4:

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <String.h>
#include <NTPClient.h>
#include <Time.h>
#include <TimeLib.h>
#include <Timezone.h>

#define WIFI_SSID      "**********"        // WiFi Network SSID (name)
#define WIFI_PASSWORD  "**********"        // WiFi Network Password

#define NTP_SERVER     "asia.pool.ntp.org" // NTP Server
#define NTP_OFFSET     3600                // NTP Time Offset (60 minutes in seconds)
#define NTP_INTERVAL   60000               // NTP Interval (60 seconds in milliseconds)

// Instantiate UDP connection object
WiFiUDP ntpUDP;

// Instantiate NTP client object
NTPClient timeClient(ntpUDP, NTP_SERVER, NTP_OFFSET, NTP_INTERVAL);

const char * days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"} ;

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

    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

    while (WiFi.status() != WL_CONNECTED) {
        delay ( 500 );
        Serial.print ( "." );
    }

    timeClient.begin();
}

void loop() {
    if (WiFi.status() == WL_CONNECTED)
    {   
        timeClient.update();

        unsigned long epochTime =  timeClient.getEpochTime();

        time_t utc = epochTime;

        TimeChangeRule myMYT = {"MYT", Second, Sun, Mar, 2, 480};  // UTC + 8 hours

        Timezone malaysianTime(myMYT, myMYT);

        time_t local;

        local = malaysianTime.toLocal(utc);

        char dateTime[32];

        sprintf(dateTime,
                "%s, %02d/%02d/%04d %02d:%02d:%02d",
                days[weekday(local)],
                day(local),
                month(local),
                year(local),
                hour(local),
                minute(local),
                second(local));

        Serial.println(dateTime);
    }

    delay(1000);
}

Memory corruption issue in Example

Hello!
In the example WorldClock, on line 89, char chMon[3] is declared with the size of 3.
However subsequent code, namely chMon[3] = '\0'; is writing to the 4th word of the array, which is not allocated by the declaration. This results into a buffer overflow and writes into arbitrary memory. I suggest fixing the issue by altering the declaration of chMon[3] to chMon[4] on line 89.

Regards,
Benedikt

Variation in time - United Arab Emirates

I'm from UAE. I Am trying to set the time change rule.

UAE is 4 hours ahead of UTC. So, I edited the rule as below.

#define NTP_ADDRESS  "ae.pool.ntp.org" 

& also

TimeChangeRule utcRule = {"UTC", Last, Sun, Mar, 1, +240};     // UTC + 4 hours for AE
Timezone myTZ(utcRule, utcRule);
local = myTZ.toLocal(utc);

But i am getting the result as 1 hour more than the actual UAE time, ie if the actual time is 10 PM, i get the result as 11 PM.

Am i doing it wrong??

library.properties too strict

The timezone library has a library.properties that lists architectures=avr. This is too strict: the library works just fine on other architectures, I've been using it on both esp8266 and esp32 successfully for a long time.

But now I am working on a platformio project where I need to set lib_compat_mode = strict (because I have one dependent library that only builds on esp32). And now Timezone isn't included anymore because of the architectures=avr.

printTime to String

Hi
Can someone please help me to find an easy way to get the printed results of printTime in to one String ?
I want to put the string in to an text file.

//Peter

ESP

Does this library run on ESP8266? It claims to run only on AVR architectures.

user configurable timezone

How can I use the clock example and set the timezone based on a user timezone ? and access it from other functions. Or simply, how can I change the timezone from inside a function after it is initialized?

eg:
//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 myTZ(usEDT, usEST);

Now, how can I change this to myTZ(usMDT,usMST)?

Sometimes the date and time are incorrect

I've used your code in a Weather Node project because my code didn't handle daylight savings time. But I sometimes see the time and date are incorrect. It's not consistent and I can't see a pattern to it, yet. For instance, I just restarted my node and I see the error. My local date and time is Nov. 12, 2017 11:41 AM CST, and your code is showing Nov. 12, 2017 00:55:47 CST. My node is showing Nov. 12, 2017 00:39:10 CST, but that might be a code bug on my part. My primary concern is the discrepancy between the actual time and what your code is returning. Have you seen this happen?

I've included a screenshot showing the discrepancies.

Thanks,
-Kirk

2017-11-12 11 41 58 -0600 time issues

Compatible with Teensy 3.2?

I currently have a DS1307 RTC connected to my Teensy 3.2 and I was wondering if there are any changes that need to be made to the library for it to work?

Thanks in advance!

variable declared void

Thank you for your work. I'm new to this and I am unable to verify the example sketches; the TimeZone, the TZ1 and TZ2 sketches all share a common compile error, "variable or field 'printDateTime' declared void".

What am I doing wrong or what may I be missing? I have Timezine.h, the JC_Button.h, and the Streaming.h libraries installed.

Again I'm new to this and still learning, thank you for your patience.

Timezone needs Time dependency on PlatformIO

Not sure if this is PlatformIO-specific, but unless I add the Time library (ID 44) to my project dependencies, the Timezone library (ID 76) will not build.

I tried adding:

  "dependencies":
  [
      {
          "name" : "Time",
          "frameworks" : "arduino"
      }
  ],

To the platform.json for Timezone, but PlatformIO could not find the Time library.

There is a discussion on the PlatformIO forums about this.

AVR vs SAMD Architecture

I am using Adafruit's ItsyBitsy M4 SAMD board with your Timezone library for a new project and I am getting this error message on compilation.

"WARNING: library Timezone claims to run on avr architecture(s) and may be incompatible with your current board which runs on samd architecture(s)."

Is there a work around you can advise? I really like to use your library for a project on the new board; the library has been working perfectly on the Uno and the ProTrinket boards.

Please let me know. Thank you,

Kind Regards.

Israel Summer Time

Hello,

I'm trying to use the library for switching ON and OFF summer time in Israel.
Israel uses rather different summer time dates:

Beginning on the Friday before the last Sunday in March (at 2:00 local time, or 0:00 UTC, clocks are moved forward by one hour)
Ending on the first Sunday after October 1 (at 2:00 IDT or 23:00 UTC Saturday, clocks are moved back by one hour).
(https://en.wikipedia.org/wiki/Israel_Summer_Time)

The ending is not the issue, but how can I define the beginning?

Many thanks.

IANA timezone standards

Wouldn't it be better to use IANA timezone standards, rather than US ones like EDT, etc?

Such as Americas/Chicago or Asia/Singapore.

That would enable looking up your local time source and getting the API to return to you the timezone you are in.

It also makes it more internationally acceptable - NZDT is all very well if you are in NZ and BST if you are in the UK, but to be truly international, your library should use agreed-upon timezone standard notation.

Proper way to set local time using buttons.

I have a clock that usually gets the time from wifi (ntp) but if the server is not reachable, the clock is portable, then it needs to be set manually. I did not try it yet but it looks like if I would use buttons to set the time it needs to set the utc time. What is the recommeded way to set the local time without the person setting it needing to know about utc time? Should I use myTZ.toUTC(local);?
Thanks

Daylight Saving Time

I'm having a bit of an issue working out how to set up the TimeChangeRule.

In the UK DST starts at 02:00 on the last Sunday of March where that Sunday is no later than the 30th of March. (If Sunday is the 31st then the change happens the week before!) The same rule applies for the end in October.

How can I set this as it isn't always the same Sunday?

question: TimeChangeRule variable types

Hi Jack,

Thanks so much for your lib, it's really good.

I am trying to convert a String from user input to this:

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

Can you please tell me the type of variables that are needed?

DST issue?

First, thanks to Jack for the excelent work!
I don't know if what i'm going to describe is an issue or not, but here it goes:

I have 3 LED clocks on my network and they work just fine (all of them). I'm in the Lisbon/GMT timezone and everything works just fine including DST calculation.

However, in case of a power cut , whe the 3 clocks are turned on at exact same time, some of them (randomly) don't calcutate the DST. I got the standard GMT time.
I beleive that the issue is related that all 3 clocks sync at almost same time, and the request came from the same public IP...

What puzzles me, is that i got the correct time (mens that sync worked in all 3 clocks)... So why I go the wrong DST?

If i cycle power the "wrong" clock everything syncs ok again. If I turn the clocks one by one is also ok everytime.

Thanks again for the excelent and sorry for the trouble
Joaquim from Portugal

Yes or No

Is there a Option that show only

Yes now is Daylight saving time
or
No, it is no Daylight saving time?

NZDT time calculation error

Hi JChristensen:
During using the timezone in UNO system, it is found the local time of NZDT wrong. The timezone rule is set like this:
TimeChangeRule GDS_general::unoDST = {"NZDT", Last, Sun, Sep, 2, +780}; //Daylight time = UTC + 13 hours
TimeChangeRule GDS_general::unoSTD = {"NZST", First, Sun, Apr, 2, +720}; //Standard time = UTC + 12 hours
Timezone GDS_general::unoTZ=Timezone(unoDST, unoSTD);

Now, these days, the local time is still 12 hours + UTC.
And further debug show:
1, timezone use North local,
2, the last week, maybe cause some problem in function time_t Timezone::toTime_t(TimeChangeRule r, int yr)
these lines:
if (r.week == 0)
{
t -= 7 * SECS_PER_DAY;
Serial.print(F("last week: "));
Serial.println(t, DEC);
}

also it was found with this bug (maybe), the month/day of the local time will going to crazy value, at this stage I convert to DateTime structure( using RTC lib). But still debug this timezone calculation wrong issue.

Can you help to have a look? Not very understand the 'lask week' logic in this function.
Thanks.
If make fix will update to you.
Thanks again.

Possibility of adding a specific day of the month rule

Would it be possible to have rules that instead of DOW, change on a specific day/month pair?
I heard about this requirement, but according to Wikipedia, Sweden used it in the past, but only Iran uses this kind of DST today.

output month as number not word

i tried to figure this on my own but cant see how

i use the below code as a weather station, part of it is to get time from GPS and convert it to local time

it works ok, but the month does only update when GPS/UTC does

i guess this is a very simple thing but again i could not find out, not even google could point me in the right direction

/***************************************************************************
  This is a library for the BME280 humidity, temperature & pressure sensor

  Designed specifically to work with the Adafruit BME280 Breakout
  ----> http://www.adafruit.com/products/2650

  These sensors use I2C or SPI to communicate, 2 or 4 pins are required
  to interface. The device's I2C address is either 0x76 or 0x77.

  Adafruit invests time and resources providing this open source code,
  please support Adafruit andopen-source hardware by purchasing products
  from Adafruit!

  Written by Limor Fried & Kevin Townsend for Adafruit Industries.
  BSD license, all text above must be included in any redistribution
 ***************************************************************************/

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <Time.h>                  
#include <Timezone.h> 

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 9

Adafruit_BME280 bme(BME_CS); // hardware SPI

#include <RF24.h>

#define CE_PIN   8
#define CSN_PIN 10
const byte slaveAddress[5] = {'R','x','A','A','A'};
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

struct package
{
  int temperature ;
  int pressure;
  int humidity ;
  float rain;
  int rf_hh;
  int rf_mm;
  int rf_dd;
  int rf_mo;
  int rf_yy;
};
typedef struct package Package;
Package data;


unsigned long delayTime;

#include <Adafruit_GPS.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(5, 4);

Adafruit_GPS GPS(&mySerial);

#define GPSECHO  false

boolean usingInterrupt = false;
             
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);

const byte interruptPin = 3;
volatile byte buckettips = 0;
long debouncing_time = 500; //Debouncing Time in Milliseconds
volatile unsigned long last_micros;
int Res = 0;

void setup() {

  Serial.begin(115200);
    Serial.println(F("BME280 test"));

    bool status;
    

    status = bme.begin();  
    if (!status) {
        Serial.println("Could not find a valid BME280 sensor, check wiring!");
        while (1);
    }
    
   Serial.println();
  pinMode(3, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), bucketTipped, FALLING);
  
  GPS.begin(9600);
  
  
  GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
  GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ);   // 1 Hz update rate
  GPS.sendCommand(PGCMD_ANTENNA);

  useInterrupt(true);
  
  mySerial.println(PMTK_Q_RELEASE);

  radio.begin();
  radio.setDataRate( RF24_250KBPS );
  radio.openWritingPipe(slaveAddress);

  delayTime = 1000;

  delay(1000);
  
  
}

// Interrupt is called once a millisecond, looks for any new GPS data, and stores it
SIGNAL(TIMER0_COMPA_vect) {
  char c = GPS.read();
  // if you want to debug, this is a good time to do it!
#ifdef UDR0
  if (GPSECHO)
    if (c) UDR0 = c;  
    // writing direct to UDR0 is much much faster than Serial.print 
    // but only one character can be written at a time. 
#endif
}

void useInterrupt(boolean v) {
  if (v) {
    // Timer0 is already used for millis() - we'll just interrupt somewhere
    // in the middle and call the "Compare A" function above
    OCR0A = 0xAF;
    TIMSK0 |= _BV(OCIE0A);
    usingInterrupt = true;
  } else {
    // do not call the interrupt function COMPA anymore
    TIMSK0 &= ~_BV(OCIE0A);
    usingInterrupt = false;
  }
}

uint32_t timer = millis();

void loop() { 
  
    printValues();
      radio.write(&data, sizeof(data));
        // Always use sizeof() as it gives the size as the number of bytes.
        // For example if dataToSend was an int sizeof() would correctly return 2
    resetrain();
    delay(delayTime);
    Serial.write(27);       // ESC command
    Serial.print("[2J");    // clear screen command
    Serial.write(27);
    Serial.print("[H");     // cursor to home command
    
}


void printValues() {
    uint8_t hh, mm, ss, dd, mo, yy;
    Serial.println("---Start---");
    Serial.print("Temperature = ");
    int temp_int = bme.readTemperature();
    Serial.print(temp_int);
    Serial.println(" *C");
    data.temperature = temp_int;
    Serial.print("Pressure = ");
    int pres_int = (bme.readPressure() / 100.0F);
    Serial.print(pres_int);
    Serial.println(" hPa");
    data.pressure = pres_int;
    Serial.print("Humidity = ");
    int hum_int = bme.readHumidity();
    Serial.print(hum_int);
    Serial.println(" %");
    Serial.println();
    data.humidity = hum_int;
    Serial.print("Bucket tipped ");
    Serial.print(buckettips);
    Serial.println(" times");
    data.rain = buckettips * 0.33;
    Serial.print(data.rain);
    Serial.println(" mm of rain");

 // in case you are not using the interrupt above, you'll
  // need to 'hand query' the GPS, not suggested :(
  if (! usingInterrupt) {
  // read data from the GPS in the 'main loop'
     char c = GPS.read();
    // if you want to debug, this is a good time to do it!
    if (GPSECHO)
      if (c) Serial.print(c);
  }
  
  // if a sentence is received, we can check the checksum, parse it...
  if (GPS.newNMEAreceived()) {
    // a tricky thing here is if we print the NMEA sentence, or data
    // we end up not listening and catching other sentences! 
    // so be very wary if using OUTPUT_ALLDATA and trytng to print out data
    //Serial.println(GPS.lastNMEA());   // this also sets the newNMEAreceived() flag to false
  
    if (!GPS.parse(GPS.lastNMEA()))   // this also sets the newNMEAreceived() flag to false
      return;  // we can fail to parse a sentence in which case we should just wait for another
  }


    
    Serial.print("\nTime: ");
    hh = GPS.hour;
    Serial.print(hh, DEC); Serial.print(':');
    mm = GPS.minute;
    Serial.print(mm, DEC); Serial.print(':');
    ss = GPS.seconds;
    Serial.println(ss, DEC);
    Serial.print("Date: ");
    dd = GPS.day;
    Serial.print(dd, DEC); Serial.print('/');
    mo = GPS.month;
    Serial.print(mo, DEC); Serial.print("/20");
    data.rf_mo = mo;
    yy = GPS.year;
    Serial.println(yy, DEC);
    Serial.println();

    setTime(hh, mm, ss, dd, mo, yy);
  
    time_t utc = now();
//    local = myTZ.toLocal(utc, &tcr);
    printDateTime(CE, utc);    
    
  }

// given a Timezone object, UTC and a string description, convert and print local time with time zone
void printDateTime(Timezone tz, time_t utc)
{
    uint8_t rf_hh, rf_mm, rf_dd, rf_mo, rf_yy;
    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 %.2d %s %d",
        hour(t), minute(t), second(t), day(t), m, year(t));
    Serial.println(buf);
    data.rf_hh = hour(t);
    data.rf_mm = minute(t);
    data.rf_dd = day(t);
    data.rf_yy = year(t);
    Serial.print("---End---");
    
    
}

void resetrain(){

if(GPS.day == 1)
{
if(GPS.hour == 0)
{
if(GPS.minute == 0)
{  
if(Res == 0)
{
buckettips = 0;
Res = 1;
}
}
}
}

if(GPS.day == 1)
{
if(GPS.hour == 0)
{
if(GPS.minute == 1)
{  
Res = 0;
}
}
}
  
}

void bucketTipped() {
  if((long)(micros() - last_micros) >= debouncing_time * 1000) {
  buckettips++;
  last_micros = micros();
   }
 }

Timezone.h works no longer for esp82366 board 2.4.0, but with board 2.3.0 it is still fine

hello
why compiles Timezone.h
https://github.com/JChristensen/Timezone
with esp board 2.3.0 but not for 2.4.0 ?
perhaps which different lib or board revision?
( the Arduino Time lib is installed and included.)

error messages for 2.4.0 (2.3.0. is fine though) :

D:\Arduino\libraries\Timezone-master\Timezone.cpp:182:20: error: expected primary-expression before ')' token

     t = makeTime(tm);        //first day of the month, or first day of next month for "Last" rules
                    ^
D:\Arduino\libraries\Timezone-master\Timezone.cpp:182:20: error: 'makeTime' was not declared in this scope

D:\Arduino\libraries\Timezone-master\Timezone.cpp:183:43: error: 'weekday' was not declared in this scope

     t += (7 * (w - 1) + (r.dow - weekday(t) + 7) % 7) * SECS_PER_DAY;

D:\Arduino\libraries\Timezone-master\Timezone.cpp:183:57: error: 'SECS_PER_DAY' was not declared in this scope

Bug in several examples (the library itself is not affected).

In de function time_t compileTime() the array to hold the month string is an entry too short.
char chMon[3], *m; has size 3 entries.
chMon[3] = '\0'; assigns te 4th entry - out-of-bounds.

See: chMon in Clock.ino, WorldClock.ino and compMon in Change_TZ_1.ino, Change_TZ_2.ino.

Kind regards.

Doesn't work every 7th years

Setting the TZ start to the last sunday of the month (October, for example) is incorrect -- the time changes on the sunday after the last saturday in the month. That sunday MAY occur in the following month!!! Like in 2020.
My clock just switched from daylight savings time to standard time today (October 25,2020), when it should wait until November 1, 2020. This could be done by setting the date to the last saturday in October with a 26 hour "time" offset, but the offset is limited to 24 hours.

Displaying Hours and Minutes Separate

I am wanting to use your code to display my local time but I want to display the hours and minutes separate. I am going to draw the individual digits with neopixels on a large format clock on the wall. Is it possible to break it down into individual hours and minutes?

Suggest an example with PROGMEM zone structures

If you're going to configure a clock with a large collection of zone rules from which you will pick a single to be the active set, then you're going to want an array of zone data in flash rather than in RAM.

You might consider adding and/or altering one of the examples to illustrate that.

DST flag is on on same rules timezone

Hello
I've tested a few times and it looks that when there's no DST for a given time zone (rules for start and end are the same, as per documentation) , when checking for locIsDST(localTime) returns TRUE.
Is this expected?

Please include TimeLib.h

Hi,

I have already reported the issue on your DS3232RTC library, and this library need the same fix:

In Timezone.h, replace
#include <Time.h>
by:
#include <TimeLib.h>

Strange behavior compiled in windows

First, thanks for this library loving it so far!

I developed most of this project in Linux, then I needed to do some other stuff in a Windows environment, so booted to that and needed to re flash the MCU, so I fired up Arduino in Windows, flashed it and everything that had a DST related was set to standard instead of DST. Drove me bonkers for an hour tracking it down. I verified that incoming NTP Unix time was correct, and verified that the 'time_t utc = now();' was returning correct Unix time. Only after that was it off.

The only change that I had made, was compiling in Windows vs Linux. So I booted into Linux, compiled, flashed and the time was correct.

Mostly an FYI.

Thanks,
-Kaleb

ESP32 warning

I used this library on an ESP32 board. As far as I can see, the library works as expected, however, I have got a warning during compilation:

WARNING: Timezone library claims to run under architecture avr and may be incompatible with your current board running under architecture esp32.

I understood the author is writing code exclusive for AVR architecture so this might not be accepted as an issue but because ESP has integrated Wifi and it is very easy to request time with NTP Client, this library is very interesting for DST.

Question about using server response as input

instead of NTP responses I like to use the information contained in a server header response like:

Date: Fri, 28 Oct 2016 13:00:14 GMT

I already have received as input for Timezone.

As a newbie any hint would be appreciated.
Thanks

TimeChangeRules Brazil !!

I would like to know what would be the example rule below for Brazil:

// Zone reference "usCT" US Central Time Zone (Chicago, Houston)
TimeChangeRule usCDT = {"CDT", Second, dowSunday, Mar, 2, -300};
TimeChangeRule usCST = {"CST", First, dowSunday, Nov, 2, -360};
Timezone usCT(usCDT, usCST);

Since, in Brazil, the Standard Time is -3 and the Daylight Saving Time is -2;

And how should these initials be:

TimeChangeRule usCDT = {"CDT", ...........
TimeChangeRule usCST = {"CST", ...........

Thanks

request: update LICENSE.md file to enable git licensing support

If LICENSE.md contains the clean text of the license, git will display the license on the main repository page.
It is a really nice feature of github.
All you would need to do is copy your preferred license text into your LICENSE.md file.
CC 4.0 license, are here: https://creativecommons.org/2014/01/07/plaintext-versions-of-creative-commons-4-0-licenses/

After that, github will show the license and put a link to your license.md file and will also provide a highlight as to the licensing requirements whenever the license file is selected/read on the site.
Yeah, you loose the ability to show a cute icon in the license file but that is probably better handled in the README file anyway.
Here is a dummy repo I created to demonstrate: https://github.com/bperrybap/junk

How about using the standard POSIX ENV time definition string

Instead of reinventing the whole thing, I would suggest that you should be using the standard IBM/POSIX ENV time string. Their format is like this:

HAST10HADT,M4.2.0/03:0:0,M10.2.0/03:0:00
AST9ADT,M3.2.0,M11.1.0
AST9ADT,M3.2.0/03:0:0,M11.1.0/03:0:0
EST5EDT,M3.2.0/02:00:00,M11.1.0/02:00:00
GRNLNDST3GRNLNDDT,M10.3.0/00:00:00,M2.4.0/00:00:00
EST5EDT,M3.2.0/02:00:00,M11.1.0
EST5EDT,M3.2.0,M11.1.0/02:00:00
CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00
MST7MDT,M3.2.0/2:00:00,M11.1.0/2:00:00
PST8PDT,M3.2.0/2:00:00,M11.1.0/2:00:00

They are well known and standard. There are about 680 of them to cover all known, well defined time zones and DST parameters. Your method discards this and creates a new version that the user has to create while with the standard way, the information is already created. All you need to do it parse it out. All you need is there.

Just a suggestion. Surely would make your code easier to use.

Mike

add esp8266 to the library.properties

I've used this library with the ESP8266 for a few months now. works flawlessly, but the arduino IDE gives a warning "may not be compatible" because the library.properties file lists avr as it's only architecture. I can confirm that esp8266 works with this library, I've modified it on my end, but it might be nice to newbies if you add 8266 to the supported architectures.

architectures=avr,esp8266

Conflicts with windows not being case sensitive

The code has a dependency on Time.h .
Unpleasantly there is also a time.h embedded in the Arduino IDE
This unfortunate issue of two files that are considered identical by Windows results in time.h being used and the many compile errors produced make the troubleshooting frustrating. The work around is to rename Time.h to something like MyTime.h and then chase down the includes within includes within includes to replace all references to Time.h and Time.cpp with MyTime.h and MyTime.h

Very big numbers does not work

I try to create a Daysafingtime yes or no

my idea is i enter crazy numbers and make than a if Year is = Year => no Daysafingtime, else yes Daysafingtime

but

TimeChangeRule myDST = {"EDT", Second, Sun, Mar, 2, -198201600}; //Daylight time = UTC - litte more than a year
TimeChangeRule mySTD = {"EST", First, Sun, Nov, 2, -300}; //Standard time = UTC - 5 hours
Timezone myTZ(myDST, mySTD);

are ignored. look like a bug.

ESP32-board writeRules : undefined reference

Hi Jack,

I'm using the Arduino IDE on an ESP32 board. It seemed to work fine, until I tried to write the rules to EEPROM. I checked your example 'WriteRules.ino' and it gives the same error. Is it suppose to work on an ESP32..?

I get this error:

undefined reference to `Timezone::writeRules(int)'

Using this lib to set RTC to UTC

Hello,

I own an Adafruit Data Logger Shield https://www.adafruit.com/product/1141

I followed this tutorial https://learn.adafruit.com/adafruit-data-logger-shield/using-the-real-time-clock

This part of code

if (! rtc.initialized()) {
  Serial.println("RTC is NOT running!");
  // following line sets the RTC to the date & time this sketch was compiled
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

adjust RTC to computer date/time... but it's using computer local date/time.

I'm looking for a way to adjust RTC using UTC when programming Arduino.

Similar question on SO https://arduino.stackexchange.com/questions/38581/setting-time-to-utc-with-data-logger-shield-with-rtc-ds1387

I wonder how this library could help to achieve this task.

Kind regards

In library.properties, architectures=avr throws warning when compiled on ESP8266

When compiling anything with the Timezone library using board ESP8266 version 2.4.1, I get the following warning:

WARNING: library Timezone claims to run on (avr) architecture(s) and may be incompatible with your current board which runs on (esp8266) architecture(s).

Ignoring this warning is a fine workaround. However, it is distracting when cleaning up code.

Reason for this warning is this last line in library.properties:
architectures=avr
I have had no warnings or issues after changing this line to
architectures=*

As Timezone is a not very hardware specific library, I guess the risk of doing so for new or yet unknown
platforms is minimal. Please consider including this change in a future release of the Timezone library.

WorldClock Example, Compile Error

I Try to run the example in Arduino 1.8.3 but appear the follow error:

WorldClock:41: error: 'dowSunday' was not declared in this scope

TimeChangeRule usCDT = {"CDT", Second, dowSunday, Mar, 2, -300};

...

any idea?

Support for systems without EEPROM

I am working some some ESP8266 hardware that doesn't support the Arduino EEPROM library. But I wanted to support DST. It looks like this library hasn't been updated in a long time. Is it still "alive"?

I'm asking because I modified it so it can be used on the ESP8266, conditionally compiling the code requiring EEPROM. Not sure if it is worth submitting since I don't know if it would ever go into an updated library.

No work with ESP8266 and Version 2.4.0.rc2

Hello,
no working with
2.4.0.rc2 core
2.4.0.rc1 core

WorldClock Demo say Ardiuno IDE 1.8.5

exit status 1
'dowSunday' was not declared in this scope

2.3.0 core OK and yes, #include <TimeLib.h>

WARNING: library Timezone claims to run on (avr) architecture(s)

'When using the library with ESP8266 (Arduino) following warning is observed:

WARNING: library Timezone claims to run on (avr) architecture(s) and may be incompatible with your current board which runs on (esp8266) architecture(s).

The library works fine but it could be improved or extended to architectures other than AVR. I understand that the author strictly uses AVR platform, hence would encourage to use ESP8266. This library is best accompanied with NTP libraries.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.