Skip to content

klux21/limitless_times

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

128 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

limitless_times - time handling functions to overcome some annoying limits

It did bother me a while that the common time functions in C are usually not
only slow but that the common implementations don't even support any dates and
times before 1970 because they are usually unable to handle negative time_t
values. Even worse there exists that nightmare of the daylight saving rules all
over the world and a thread save conversion between the the times of different
time zones is a pretty hard thing to do. The math itself is not that hard of
course as long as you know the time offsets and the daylight saving rules.
If it comes to myself I did just want some fast, reliable and portable
functions for my applications and especially for my network loggings in the
several systems all over the world.

The wrappers for gmtime_r, mkgmtime, mktime and localtime_r here can handle the
Gregorian time even back to the age of dinosaur and the same time span ahead in
the future as well. Additionally there there are the functions mktime_of_zone()
and localtime_of_zone()now to provide a thread save conversion between the UTC
time of a time_t and the local times in random time zones and are able to handle
that bunch of the different daylight saving rules of the different zones.
For speeding up the calculations a pre-calculated conversion data is required
that contains all required time-zone information and can be generated by a call
of read_TZ() using an argument string that provides the rules in TZ format.
The TZ strings of all common timezones can be found in zones/tz_value.c .

Thread safety is a problem regarding the standard C functions mktime() and
localtime_r() because those functions rely on the environment parameter TZ
which can be required to change at runtime once the time zone is changed. This
can be a real problem in big software projects with countless components.
The C standard says about that the *_r time functions that they "shall not be
subject to data races, unless the time or calendar state is changed in a
multi-thread execution." That's why it's pretty dangerous to use those
functions in big multi-threaded and portable software projects if any time zone
adjustments or convertions at runtime need to be done.

For being thread safe you just need a call of update_time_zone_info() before
creating any threads and provide. In case that you need changes of TZ or your
local time zone during at random times once your process is running you have
to provide an own mutex lock and unlock function for init_time_api_lock().

Since version 2.1 only time64_t instead of time_t values are used. This should
cause compiler warnings if a 32 bit time_t is used for storing the return
value of a mktime() or timegm() call and should help to prevent year 2038
problems. The macros for replacing gmtime_r and localtime_r are dereferencing
the pointers outside of the function calls now and are able to handle 32 bit
and 64 bit input pointer values now. Of course the best fix of the year 2038
problems is to use 64 bit software or at least 64 bit time_t values only.

The support of the daylight saving rules is not that funny to implement but
the functions new_mktime and new localtime_r here should handle them right as
long as the environment variable TZ is set correctly.

The default value is searched in /etc/localtime if that file exists as common
in many Unix systems. The algorithm doesn't care the true binary format of
the time zone data base files but extracts the TZ value at the end of that
file only. This works in Linux and BSD but does not care about the big bunch
of the historical time offsets and daylight saving rules.
Of course I doubt that any of us will go back in time for enjoying those old
days again and for this it shouldn't be a big problem for most applications and
developers.
Be aware that the provided functions don't care about leap seconds.
Those are applied at random times for adjusting the timegap between the very
local Gregorian time and the UTC time but a Gregorian year has an even bigger
deviation from an average tropical year either and leap seconds can't fix the
problems that the GPS and other systems face either.
The Unix standard says that "As represented in seconds since the Epoch, each
and every day shall be accounted for by exactly 86400 seconds."
( https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_16 )
For this leap seconds are ignored and I guess it's pretty OK to do so.
A Gregorian year lasts currently a bit longer than a tropical year either and
in a few ten thousend years after the earth rotation has slowed down a bit more
the times will match again either and so it seems rather an academic problem.

For testing the functions and comparing the speed with the compiler build-in
functions you may execute the test_times.c right as a shell script in a Linux
or BSD system of your choice where a C compiler exist. There is are little
Visual Studio Projects as well.

The license is kind of a mix of BSD and Apache conditions but in opposite to
those it prohibits a usage for weapons and spyware and a secret monitoring of
other people without their agreement or their health or life being endangered.
That's fine for most software but usually not for military devices, weapons or
spyware. It would be great if more projects would adapt this license as well.
The list of time zones remains public domain as in the IANA time-zone database
version 2025b https://www.iana.org/time-zones.

Life is great once there are less limits and problems and for this it's about
time for limitless times now.

Kind regards,

Klaus Lux