← index #2130PR #715
Related · high · value 0.969
QUERY · ISSUE

Timezone support for "time" module

openby puuuopened 2016-05-30updated 2024-09-29
enhancement

From the release notes of MicroPython ESP8266 firmware v1.8 is clear, ntptime only supports UTC. I agree, time zone handling is out of the focus of ntptime. But it would be nice, if ntptime.settime() would support a offset argument, which is be added to ntptime.time() before setting the rtc.

Something like ntptime.settime(offset=2*3600) to provide CEST.
Then, getting the local time is easy as time.localtime() (if #2097 is solved).

I believe, this is a simple api enhancement. Later, a timezone module may calculate the offset by time zone and daylight saving.

I can provide a pull request, but I am not sure about the api and what unit (seconds, minutes or hours) is advisable for the offset. Also the PR may conflict with #2121 .

CANDIDATE · PULL REQUEST

Update ntptime.py

closedby yanzhonghuiopened 2023-08-10updated 2023-09-06

Add time zone offset support

5 comments
MrEbbinghaus · 2023-08-31

The epoch time is ALWAYS expected to be in UTC. Changing it here would break a lot of stuff.

For example, after setting the time with ntptime.settime(), time.gmttime() wouldn't return GMT(/UTC) time any more.

Also, there are timezones that aren't offset by a whole hour.


But I understand where you want to go with this.

I did something similar this week, but added the timezone offset to the time module.
And used the offset only in the localtime() function.

Something like:

my_time.py


import time
TZ_OFFSET = 0

def localtime(secs=None):
  return time.localtime((secs if secs else time.time()) + TZ_OFFSET)
projectgus · 2023-09-05

Thanks @MrEbbinghaus for gathering all these PRs together. I generally agree with your conclusion and suggested approach.

Many (but I think not all) ports are built with MICROPY_PY_TIME_GMTIME_LOCALTIME_MKTIME support which implements 90% of what's needed for CPython compatible timezone support inside extmod/modtime.c. At first glance, the only thing that's missing to implement for basic embedded-friendly time zones is time.timezone, and the fact that gmtime() and localtime() are implemented as the same function.

I feel like there's probably a good reason why this isn't implemented already, though. @dpgeorge and @jimmo might know?

MrEbbinghaus · 2023-09-05

We should have this discussion somewhere else and close those PRs. NTP and timezones are separate things. Changing the epoch time when setting the time through NTP would be semantically wrong and a breaking change.


I guess complete time zone database support would be unnecessary in most projects.

One could implement something like time.tzset() for the first and second TZ format.
For my current timezone, this would be:
CET-1 (without DST info)
CET-1CEST,M3.5.0,M10.5.0/3 (with DST info)

From that we could set time.daylight, .timezone, .tzname and .altzone

And tm_zone, tm_isdst and tm_gmtoff in struct_time.
Although I'm not sure if you could add named fields to the tuple MircoPython is returning without breaking existing code, that relies on that tuple. My python knowledge isn't enough to say.


The first format (CET-1) would be very simple:

input = "CET-1"

format_1 = re.compile(r"^([A-Z]+)([+-]?)(\d+)(?::(\d+))?(?::(\d+))?")

>>> re.match(format_1, input).groups(default=0)
('CET', '-', '1', 0, 0)
>>> tzname, sign, d_hour, d_min, d_sec = re.match(format_1, input).groups(default=0)

offset = (int(d_hour) * 60 + int(d_min)) * 60 + int(d_sec)
timezone = offset * (1 if sign == "-" else -1)

altzone = timezone
daylight = 0

###
tm_gmtoff = altzone if daylight != 0 else timezone
tm_zone = tzname

The second format (CET-1CEST,M3.5.0,M10.5.0/3) would be more difficult.

projectgus · 2023-09-06

@MrEbbinghaus Good ideas, both on moving this discussion to a more suitable place, and the possibility of simplified timezone string support.

I've summarised all of the existing discussion and options I could find, here: https://github.com/orgs/micropython/discussions/12378 - please reply with more thoughts or suggestions.

@yanzhonghui As discussed above, everyone agrees MicroPython should solve this problem but the best place is probably not in the ntptime module. As such, I'm going to close this PR. Please comment on the linked discussion if you have any suggestions for what should be done!

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied