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

Please consider using GMT or UTC for "tzdflt" #49

Closed
drawkula opened this issue Nov 9, 2016 · 10 comments
Closed

Please consider using GMT or UTC for "tzdflt" #49

drawkula opened this issue Nov 9, 2016 · 10 comments

Comments

@drawkula
Copy link

drawkula commented Nov 9, 2016

(root@minoca:pty2)~# strings /dev/Volume/Volume1/minoca/config/tzdflt 
TmZn,
America/Los_Angeles
P%sT
@drawkula drawkula changed the title Please consider using GMT or UTC as "tzdflt" Please consider using GMT or UTC for "tzdflt" Nov 9, 2016
@evangreen
Copy link
Collaborator

I dunno, something's got to be the default. Why is UTC better? We probably also need a better tool for changing the time zone in the kernel. Or maybe just a better story for time zones in general that keeps the kernel out of it. The sticky spot is the hardware RTC, which is often programmed in local time.

Did you figure out how to change this in the build for your own purposes? It's line 44 of apps/tzcomp/Makefile.

@drawkula
Copy link
Author

drawkula commented Nov 9, 2016

Why is UTC better?

GMT kind of is the "zero" of timezones.

Why is some random "nonzero" timezone default value better than GMT?

@evangreen
Copy link
Collaborator

Probably the better solution is to figure out how to get the kernel out of the business of knowing the time zone. Right now the kernel is aware of local time in order to support the HlHardwareTimeIsLocal boolean in kernel/hl/calendar.c, which enables support for hardware RTCs that are programmed with local time rather than UTC time.

We could abandon this feature, which would mean the hardware timer is always programmed with UTC time. The downside is joining that same fight that all other OSes have of battling with Windows to set the UTC version of the RTC (Windows wants to set it in local time). But the upside is not having to assign a time zone to the kernel, which is probably worth it.

We'd also need a substitute mechanism for getting the time zone data in each app, which right now is a system call that pulls it all down from a kernel buffer. That's pretty hokey anyway, so I'm not opposed to getting rid of that and using a traditional file approach. We'd also need to tweak an init script somewhere to set a default time zone, which users could then change more easily.

@drawkula
Copy link
Author

Each user already can have her preferred TZ setting in her shell startup files... or for each command... even fairly nonstandard ones...

(yeti@minoca:pty8)~$ export TZ ; touch xyzzy ; for TZ in GMT OBFT+0:15 ZELZ-2 ; do date ; ls -l xyzzy ; echo ; done
Tue Nov 29 17:03:10 GMT 2016
-rw-r--r--  1 yeti users  0 Nov 29 17:03 xyzzy

Tue Nov 29 16:48:10 OBFT 2016
-rw-r--r--  1 yeti users  0 Nov 29 16:48 xyzzy

Tue Nov 29 19:03:10 ZELZ 2016
-rw-r--r--  1 yeti users  0 Nov 29 19:03 xyzzy

(yeti@minoca:pty8)~$ █

OBFT = off by 15min
ZELZ = Zentral-Europäische Lügen-Zeit (CET's DST)

What does the kernel need? An idea of time intervals (some ticks and knowing their length) and how many ticks have passed since system startup. The rest is a job for libc, libtime or other helpers.

The kernel's relative view of time needs to be anchored in absolute time somewhen or logging always stays relative to the time of last boot... a hint about the real time may be fetched from the onboard RTC (or even from a stored value of the last timestamp before the previous shutdown (see "fake-hwclock")) and later will be corrected using NTP, GPS, ...

The main issue is to be able to change the configuration without recompiling. Then probably nobody will ask what happens under the hood.

@evangreen
Copy link
Collaborator

Yes, what you're saying is correct. The kernel's concept of time is simply a SYSTEM_TIME structure, which stores seconds and nanoseconds since 2001, so there is no concept of a time zone. There's an annoying wrinkle though, which I'll try to explain below.

The very annoying wrinkle that brings time zones into the kernel is the hardware RTC. The hardware RTC reports the current time in calendar units, for instance Y=2016 m=11 D=29 H=09 M=58 S=30. So after you read from the RTC you have to convert that to "seconds since 2001". Unfortunately the RTC doesn't also store time zone information. The easy option, which is what nearly all OSes do, is to assume the calendar time read from the RTC is in UTC. Unfortunately, Windows sets the RTC to local time, so when you read 2016/11/29 09:58:30, it's really more like 18:58:30 for me (on PST-8). So if the kernel is going to support an RTC that is programmed in local time, which is what HlHardwareTimeIsLocal was trying to do, you have to know how much to add to the value read by the RTC in order to convert to "seconds since 2001".

It's a big enough design blemish that it's probably not worth supporting HlHardwareTimeIsLocal. If we remove that variable and all references to it, then the kernel doesn't need to know about time zones at all, as it only ever converts that calendar time into seconds since 2001 using UTC time.

@drawkula
Copy link
Author

drawkula commented Nov 29, 2016

Whatever decision is drawn, always someone will complain.

Having a fixed offset between hardware time and system time only has an impact when interacting with the hardware clock. So defining system time to be UTC and keeping HlHardwareTimeIsLocal will only be a small complexity. Just know the difference. The rest is a userland story.

@drawkula
Copy link
Author

drawkula commented Nov 29, 2016

EEeeeeehhhhhh... but running the onboard RTC on local time and then having dual-boot with an OS that may or may not have been booted since the last switch to or from DST has taken place and will set the DST back into the RTC or the other way round is a different dimension of madness. You never can be really sure which timezone you have in the RTC. Even HlHardwareTimeIsLocal is no guarantee to interpret the RTC's time correctly.

I often forget this opera...
:-(


Added 20170906-0026-GMT: https://xkcd.com/1883/ ;-)

@evangreen
Copy link
Collaborator

Yep, you're right about that. Trying to store the RTC in local time is a real mess. Additionally, there are hours that do not exist and hours that exist twice in local time, so figuring out what to do when the RTC reads times in those regions is no fun.

UTC seems like the only sane answer.

@evangreen
Copy link
Collaborator

Okay, I've made some changes in this region. If you pull the latest from master, you'll find that the kernel is no longer time-zone aware. There is still a default of America/Los_Angeles, but it's in a file /etc/tz. The entire almanac is in /usr/share/tz/tzdata. A new app can be used to change the default time zone (eg tzset America/New_York). The TZ environment variable now also supports things like TZ=:America/Chicago and TZ=:/etc/tz2.

@evangreen
Copy link
Collaborator

I'm going to go ahead and close this, feel free to reopen if you want to talk more about the solution I've put in here.

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

2 participants