ropg / ezTime

ezTime — pronounced "Easy Time" — is a very easy to use Arduino time and date library that provides NTP network time lookups, extensive timezone support, formatted time and date strings, user events, millisecond precision and more.
MIT License
327 stars 92 forks source link

Two global timezones? #36

Closed JasXSL closed 5 years ago

JasXSL commented 5 years ago

Is it possible to have multiple global scoped timezones independent of each other?

I have the following code: '

#include 
#include 
#define CONF_TIMEZONE "Europe/Stockholm"
const char *ssid     = "ssid";
const char *password = "pass";
Timezone tz;
Timezone tempTime;
void setup() {
    Serial.begin(115200);
    Serial.println("Serial run");
    WiFi.begin(ssid, password);
    while( WiFi.status() != WL_CONNECTED ){
        delay( 500 );
        Serial.print ( "." );
    }
    waitForSync();
    tempTime.setLocation(CONF_TIMEZONE );
    tz.setLocation(CONF_TIMEZONE );
    tz.setDefault();

    Serial.println("Time: "+tz.dateTime());
    tempTime.setTime(
        12, // H 
        0,  // M
        0,  // S
        1,1,2018
    );
    Serial.println("tz after setting tempTime");
    Serial.println(tz.dateTime());
}

void loop(){ delay(1000); }

After setting time on tempTime, it also changes the time of tz.

The reason is I want to be able to get the unix timestamp a day ahead of current time, while maintaining the current time to output onto a display every second.

I tried creating a new Timezone tempTime, when doing the comparison, but doing that added a delay of more than 1 second.

JasXSL commented 5 years ago

Did the test with timezones created in setup, and updated my ESP libraries just in case. And I have the same issue. Can you only have one Timzeone object at a time in a project?

JasXSL commented 5 years ago

Tried using makeTime instead, but the result seems to be wrong. Here's my code:

void setup() {
    Serial.begin(115200);
    Serial.println("Serial run");
    WiFi.begin(ssid, password);
    while( WiFi.status() != WL_CONNECTED ){
        delay( 500 );
        Serial.print ( "." );
    }

    waitForSync();
    tz.setLocation(F("Europe/Stockholm"));
    tz.setDefault();
    Serial.println("Time: "+tz.dateTime());
    Serial.printf("Setting clock to 02:00:00 on YMD %i-%i-%i\n", tz.year(), tz.month(), tz.day());
    time_t startTime = makeTime(
        2, 
        0, 0,
        tz.day(), 
        tz.month(), 
        tz.year()
    );
    Serial.println(startTime);
    Serial.println("tz after setting tempTime");
    Serial.println(dateTime(startTime));
}

Output:

Serial run
.....Time: Tuesday, 19-Mar-2019 02:53:04 CET
Setting clock to 02:00:00 on YMD 2019-3-19
1552960800
tz after setting tempTime
Tuesday, 19-Mar-2019 01:00:00 CET

I'm thinking makeTime doesn't account for timezone?

ropg commented 5 years ago

There is only one time that is kept. By setting it in a specific timezone, you are telling ezTime what time it is in that timezone, which will then be translated to UTC before setting the one single time that is kept. (This one single time is just a periodically corrected offset between Arduino's millis() counter and the actual UTC time.)

If you want a timestamp for 24 hrs ahead, simply use now() + (24 * 3600).

JasXSL commented 5 years ago

I want to get the Unix time of 2am in my local time zone, is that not possible then?

ropg commented 5 years ago

If you want the unix time (i.e. UTC seconds since 1970) of 24 hrs ahead of now in local timezone, that would be UTC.now() + (24 * 3600).

As for "2 am": what do you want to do if it's between midnight and 2 am? Get the upcoming 2am or the previous one?

Either way, you'll have to figure the logic out yourself but you could use makeTime() and provide time and date values to create a time in UTC seconds to create a timestamp and then use yourLocalTimeZone.getOffset() to see how many minutes (so times 60 for seconds) to add or subtract.

JasXSL commented 5 years ago

I want to get the unix timestamp of 2 AM of the current day of my selected time zone. I tested this with setTime and it works. Basically how JavaScript has:

new Date("2019-03-31 01:59:59").getTime()/1000 = 1553993999
new Date("2019-03-31 03:00:00").getTime()/1000 = 1553994000 (just 1 sec difference because of DST)

I'm assuming yourLocalTimeZone.getOffset() only returns the offset of the current time, and not the offset at a specific point in time?

ropg commented 5 years ago

maketime(2,0,0,yourTZ.day(),yourTZ.month(),yourTZ.year()) - ( yourTZ.getOffset() * 60 )

The first part gets you 2 am UTC for the date in your timezone, the second part subtracts the offset, because the offset is in minutes west of UTC, and you want to add for going east and subtract for west.

wyojustin commented 4 years ago

Thanks @ropg for the awesome library. I just came accross this issue in my own project. I'm making a multi timezone clock that needs multiple independent zones. Can you outline what it would take to upgrade ezTime to multiple zones?

ropg commented 4 years ago

Not sure I understand. You can make as many timezones as you want. For example:

Timezone NZtime;
Timezone DEtime;

NZtime.setLocation("Pacific/Auckland");
Serial.print("New Zealand: ");
Serial.println(NZtime.dateTime());

// Wait a little bit to not trigger DDoS protection on server
// See https://github.com/ropg/ezTime#timezonedropnl
delay(5000);

DEtime.setLocation("Europe/Berlin");
Serial.print("Germany: ");
Serial.println(DEtime.dateTime());
wyojustin commented 4 years ago

Ok. I missed that. Thank you. Justin

On Sat, Dec 14, 2019 at 3:16 AM Rop Gonggrijp notifications@github.com wrote:

Not sure I understand. You can make as many timezones as you want. For example:

Timezone NZtime; Timezone DEtime;

NZtime.setLocation("Pacific/Auckland"); Serial.print("New Zealand: "); Serial.println(NZtime.dateTime());

// Wait a little bit to not trigger DDoS protection on server // See https://github.com/ropg/ezTime#timezonedropnl delay(5000 https://github.com/ropg/ezTime#timezonedropnldelay(5000);

DEtime.setLocation("Europe/Berlin"); Serial.print("Germany: "); Serial.println(DEtime.dateTime());

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ropg/ezTime/issues/36?email_source=notifications&email_token=AAG5AW6TASTVBCNWMHBFKEDQYSI6HA5CNFSM4G7DCSF2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEG35CRI#issuecomment-565694789, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAG5AW727XYTIWKHDOVQAA3QYSI6HANCNFSM4G7DCSFQ .

-- Justin