I'm working on a linux embedded project built with buildroot tool and I'm using mono to run my .net application on linux system. It's necessary to have a custom table of daylight saving time periods. The user will insert manually the next few years periods(when daylight saving time starts and when it ends) in a GUI interface that I have done in .net, and the user is allowed to edit those periods if they change by the government. I know maybe there are other way to do that automatically, but like I said, it's necessary to have an user interface to set or edit it manually.
Before I was using this file as my zoneinfo information:
/usr/share/zoneinfo/America/Sao_Paulo
This file has the daylight saving time periods of São Paulo and Linux changes the system clock automatically when it starts, but I found out I can't edit this file, so it doesn't work for me. So I changed to:
/usr/share/zoneinfo/Etc/GMT+3
This file has my zoneinfo without daylight saving time periods. I'm planning to do it manually.
I did the GUI interface which saves the table of custom DST periods in mongodb database. My idea was to set the linux system clock one hour a head when I detect the current time is within of any period saved in my database. It also was working very well but the problem is when my NTP service synchronizes and updates the system clock, setting it to one hour behind back again. And of course, I can't disable the NTP service, I need this as well.
How can I implement this feature ? Is it better implementing this in Linux to do this task or in my .net application running on linux ?
You can either write your own replacement of localtime(), or use the zic tool.
First of all, however: you probably don't want to do this. Quoting @Panagiotis:
The tz database files are updated regularly and distributed automatically. In fact they are the defacto standard.
In fact, the "regularly updated" is mostly for historical timezone information, because timezones simply don't change that often. In Buildroot, simply install the tzdata
package and you have all the timezones in the world.
For applying the timezone information, you always want to do that as late as possible. The system clock must be in UTC. Timestamps on files should be in UTC as well. Modern system loggers (e.g. systemd-journald) also store timestamps in UTC. All times communicated over the network should be in UTC. Only when a time is presented to the user it is necessary to convert it to local time (which may be different for different users).
To solve your problem with custom timezones, the easiest is to not use the normal localtime() (or whatever the .NET equivalent is) but instead use a wrapper function that first checks if the current timezone is one of the custom timezones, and do your own timezone calculations in that case.
Alternatively, you can generate a timezone file and write it to the filesystem. The tzfile format is a binary format, so probably it is easier to generate a text file and convert it with the zic tool. In Buildroot, the zic tool is not currently available for the target, so you'll need to update package/zic/zic.mk
and add package/zic/Config.in
. You can look at how Buildroot generates the timezone files from the tzdata
rules file in package/tzdata/tzdata.mk
.
If you really need the timezone to be configured system-wide (which you typically don't need to do), you have to create a symlink to the custom timezone from /etc/localtime
and set it in /etc/timezone
. And of course, you have to make sure that the custom timezone file is writable. I would advice to give your timezones non-standard names, e.g. starting with Custom/, and make /usr/share/zoneinfo/Custom
a symlink to a writable directory.