Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timezone not applying to makeTime #10

Open
chinswain opened this issue Oct 26, 2018 · 4 comments
Open

Timezone not applying to makeTime #10

chinswain opened this issue Oct 26, 2018 · 4 comments

Comments

@chinswain
Copy link
Contributor

Is this expected behavior? I'm sure I'm doing something silly but If I set up a time_t element it prints without timezone adjustment.

The default timezone works, deconstructing t shows the hour as 21 and the epoch time is correct.

#include <ezTime.h>
#include <WiFi.h>
Timezone myTZ;

void setup() {
  Serial.begin(115200);
  WiFi.begin("", "");
  waitForSync();

  myTZ.setLocation(F("gb"));
  myTZ.setDefault();
  Serial.print("TimeZone: "); Serial.println(dateTime());
  Serial.print("epoch myTZ : "); Serial.println(myTZ.now());
  
  time_t t = 0;
  t = makeTime(21, 45, 00, myTZ.day() , myTZ.month(), myTZ.year());
  Serial.print("Test: "); Serial.println(myTZ.dateTime(t));

  Serial.print("epoch Test : "); Serial.println(t);

  tmElements_t tmTest;
  breakTime(t, tmTest);
  Serial.print("Hour: "); Serial.println(tmTest.Hour);
}

void loop() {

}
TimeZone: Friday, 26-Oct-2018 21:45:27 BST
epoch myTZ : 1540590327

Test: Friday, 26-Oct-2018 20:45:00 BST
epoch Test : 1540590300

Hour: 21

@ropg
Copy link
Owner

ropg commented Oct 27, 2018

makeTime is timezone-agnostic on purpose: it just converts between two ways of writing time. So yes, it would represent in UTC. Not sure what the bigger-picture things is you are trying to accomplish, but you can use tzTime to convert epoch seconds in one timezone to another.

@ropg ropg closed this as completed Oct 27, 2018
@bperrybap
Copy link

@ropg

you can use tzTime to convert epoch seconds in one timezone to another.

But that isn't the way time_t values are supposed to work.
A time_t value denotes a specific point in time by specifying an elapsed amount of time since a single point in time known as the Epoch. There is only a single Epoch. The Epoch is not a specific datetime within a timezone.
A time_t value does not depend on or is not modified by the timezone or any local time conversion rules.
A time_t does not represent an elapsed time from some point in time based on a local timezone.
A time_t represents the number of seconds since Jan 1, 1970 00:00:00 UTC (not counting leap seconds)
i.e. there is no such thing as a local time time_t value
(These types of munged/modified local time time_t values can be useful under the hood internal to the library but should never be exposed back up to the application)

At any given point in time, the time_t value returned to the application is same value in EVERY timezone on the planet.

It has to work this way to be able to do timestamping and to be able to easily convert individual time_t values to local datetimes and broken down values.

I wrote about this some more in this Arduino thread:
https://forum.arduino.cc/index.php?topic=568903.0

I'll soon be creating another issue about time_t values not being handled properly and a recommendation with more details of how to fix it.
The summary is that all time_t values should represent an offset from the single Unix epoch.
(this is how they work on unix/linux)
To make that happen:

  • all now() functions must return the same time_t value from the Unix epoch.
  • All functions that receive a time_t argument must accept a proper Unix epoch time_t value
  • makeTime() moves to the Timezone class so it can convert from local time fields to a Unix epoch time_t
  • breakTime() moves to the Timezone class to do the reverse of makeTime()
  • compileTime() must return a tmElements or be moved to the TimeZone class since there is no way to create a proper time_t value from the compiler provided local date/time info without having timezone information.

Once this is done, there is no longer a need to specify UTC vs LOCAL since proper Unix time_t values are always from the Unix Epoch and all functions will be using/returning time_t values from the same single epoch.

For most users, correcting the code to use proper Unix time_t values will be completely transparent.

@ropg
Copy link
Owner

ropg commented Jan 22, 2019

I guess when I wrote this I wanted to make it a replacement for Arduino Time library that didn't have timezones, and I didn't want to break code that uses makeTime() and breakTime() by producing unexpected answers to code that isn't timezone-aware.

But I see your point. I've reopened the issue, and as soon as I get some time to sit down with ezTime (early March?), I'll probably implement it the way you suggest. Might come back to you to bounce ideas back and forth at that time, if I may.

@ropg ropg reopened this Jan 22, 2019
@bperrybap
Copy link

Sounds good. Look forward to working with you on this.
Funny about the Time/TimeLib library not supporting timezones. I kidded Michael (The original author) about it. It wasn't a priority for him since he lived in London which doesn't need any offset from UTC.

I think it is possible to provide compatibility with existing TimeLib sketch code and use proper time_t values by having both ezt and TimeZone makeTime() and breakTime().

What will be difficult will be to maintain compatibility with the current ezTime API behavior. But if that is important, it is probably possible with some additional constructor parameters that set flags/states/modes in the Timezone object.
But we can dig into it further, when you are ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants