Custom Calendars in C/C++
Adding new calendars to Calends is a fairly straightforward process. Implement a handful of functions, and then simply pass them to the registration function.
Define
The functions in question look like this:
-
TAI64Time Calends_calendar_to_internal_string(char *calendar, char *date, char *format)
-
TAI64Time Calends_calendar_to_internal_long_long(char *calendar, long long int date, char *format)
-
TAI64Time Calends_calendar_to_internal_double(char *calendar, double date, char *format)
-
TAI64Time Calends_calendar_to_internal_tai(char *calendar, TAI64Time date)
- Parameters
calendar (
char*
) – The name of the target calendar system.date (
char*
orlong long int
ordouble
orTAI64Time
) – The input date.format (
char*
) – The format string for parsing the input date.
- Returns
The parsed internal timestamp.
- Return type
Converts an input date/time representation to an internal
TAI64Time
.
-
char *Calends_calendar_from_internal(char *calendar, TAI64Time stamp, char *format)
- Parameters
calendar (
char*
) – The name of the target calendar system.stamp (
TAI64Time
) – The internal timestamp value.format (
char*
) – The format string for formatting the output date.
- Returns
The formatted date/time.
- Return type
char*
Converts an internal
TAI64Time
to a date/time string.
-
TAI64Time Calends_calendar_offset_string(char *calendar, TAI64Time stamp, char *offset)
-
TAI64Time Calends_calendar_offset_long_long(char *calendar, TAI64Time stamp, long long int offset)
-
TAI64Time Calends_calendar_offset_double(char *calendar, TAI64Time stamp, double offset)
-
TAI64Time Calends_calendar_offset_tai(char *calendar, TAI64Time stamp, TAI64Time offset)
- Parameters
- Returns
The adjusted internal timestamp.
- Return type
Adds the given offset to an internal
TAI64Time
.
Registration
Register
Once it is registered with the library, your calendar system can be used from anywhere in your application. To register a system, pass it to the following function:
- void Calends_calendar_register(char* name, char* defaultFormat, Calends_calendar_to_internal_string() to_internal_string, Calends_calendar_to_internal_long_long() to_internal_long_long, Calends_calendar_to_internal_double() to_internal_double, Calends_calendar_to_internal_tai() to_internal_tai, Calends_calendar_from_internal() from_internal, Calends_calendar_offset_string() offset_string, Calends_calendar_offset_long_long() offset_long_long, Calends_calendar_offset_double() offset_double, Calends_calendar_offset_tai() offset_tai)
- Parameters
name (
char*
) – The name to register the calendar system under.defaultFormat (
char*
) – The default format string.to_internal_string (
Calends_calendar_to_internal_string()
) – The calendar parser, forchar*
input.to_internal_long_long (
Calends_calendar_to_internal_long_long()
) – The calendar parser, forlong long int
input.to_internal_double (
Calends_calendar_to_internal_double()
) – The calendar parser, fordouble
input.to_internal_tai (
Calends_calendar_to_internal_tai()
) – The calendar parser, forTAI64Time
input.from_internal (
Calends_calendar_from_internal()
) – The calendar formatter.offset_string (
Calends_calendar_offset_string()
) – The calendar offset calculator, forchar*
input.offset_long_long (
Calends_calendar_offset_long_long()
) – The calendar offset calculator, forlong long int
input.offset_double (
Calends_calendar_offset_double()
) – The calendar offset calculator, fordouble
input.offset_tai (
Calends_calendar_offset_tai()
) – The calendar offset calculator, forTAI64Time
input.
Registers a calendar system class, storing the collected functions as
name
, and savingdefaultFormat
for later use while parsing or formatting.
Unregister
-
void Calends_calendar_unregister(char *name)
- Parameters
name (
char*
) – The name of the calendar system to remove.
Removes a calendar system from the callback list.
Check and List
-
bool Calends_calendar_registered(char *name)
- Parameters
name (
char*
) – The calendar system name to check for.
- Returns
Whether or not the calendar system is currently registered.
- Return type
bool
Returns whether or not a calendar system has been registered, yet.
-
char *Calends_calendar_list_registered()
- Returns
The sorted list of calendar systems currently registered.
- Return type
char*
Returns the list of calendar systems currently registered.
Types and Values
Now we get to the inner workings that make calendar systems function – even the
built-in ones. The majority of the «magic» comes from the TAI64Time
struct itself, as a reliable way of storing the exact instants being calculated,
and the only way times are handled by the library itself. A handful of functions
provide basic operations that calendar system developers can use to simplify
their conversions (adding and subtracting the values of other timestamps, and
importing/exporting timestamp values from/to other types, in particular), and a
couple of helpers exclusively handle adding and removing UTC leap second
offsets. As long as you can convert your dates to/from Unix timestamps in a
char*
, long long int
, or double
, the rest is
handled entirely by these helpers in the library itself.
-
type TAI64Time
Stores a
TAI64NARUX
instant in a reliable, easy-converted format. Each 9-digit fractional segment is stored in a separate 32-bit integer to preserve its value with a very high degree of accuracy, without having to rely on string parsing or external arbitrary-precision math libraries.-
long long int seconds
The number of TAI seconds since
CE 1970-01-01 00:00:00 TAI
Note
TAI vs UTC
You may have noticed that a TAI64Time object stores times in
TAI seconds
, notUnix seconds
, with a timezone offset ofTAI
rather thanUTC
. This distinction is very important as it will affect internal calculations and comparisons to mix the two up. TAI time is very similar to Unix time (itself based on UTC time), with one major difference. While Unix/UTC seconds include the insertion and removal of «leap seconds» to keep the solar zenith at local noon (which is useful for day-to-day living and planning), TAI seconds are a continuous count, unconcerned with dates whatsoever. Indeed, the only reason a date was given in the description above was to make it easier for human readers to know exactly when0 TAI
took place.In other words, once you have a Unix timestamp of your instant calculated, be sure to convert it using
TAI64Time_utc_to_tai()
before returning the result to the rest of the library. And then, of course, you’ll also need to convert instants from the library back usingTAI64Time_tai_to_utc()
before generating outputs.
-
unsigned int nano
Nanoseconds since the given second
-
unsigned int atto
Attoseconds since the given nanosecond
-
unsigned int ronto
Rontoseconds since the given attosecond
-
unsigned int udecto
Udectoseconds since the given rontosecond
-
unsigned int xindecto
Xindectoseconds since the given udectosecond
-
unsigned int padding
Unused, except to round the value out to the nearest 64 bits
-
long long int seconds
Calculations
Export
-
char *TAI64Time_string(TAI64Time t)
- Parameters
t (
TAI64Time
) – The current timestamp.
- Returns
The decimal string representation of the current timestamp.
- Return type
char*
Returns the decimal string representation of a
TAI64Time
value.
-
TAI64Time TAI64Time_from_string(char *in)
- Parameters
in (
char*
) – The decimal string representation of a timestamp to calculate.
- Returns
The calculated timestamp.
- Return type
Calculates a
TAI64Time
from its decimal string representation.
-
char *TAI64Time_hex_string(TAI64Time t)
- Parameters
t (
TAI64Time
) – The current timestamp.
- Returns
The hexadecimal string representation of the current timestamp.
- Return type
char*
Returns the hexadecimal string representation of a
TAI64Time
value.
-
TAI64Time TAI64Time_from_hex_string(char *in)
- Parameters
in (
char*
) – The hexadecimal string representation of a timestamp to calculate.
- Returns
The calculated timestamp.
- Return type
Calculates a
TAI64Time
from its hexadecimal string representation.
-
double TAI64Time_double(TAI64Time t)
- Parameters
t (
TAI64Time
) – The current timestamp.
- Returns
The arbitrary-precision floating point representation of the current timestamp.
- Return type
double
Returns the
double
representation of aTAI64Time
value.
-
TAI64Time TAI64Time_from_double(double in)
- Parameters
in (
double
) – The arbitrary-precision floating point representation of a timestamp to calculate.
- Returns
The calculated timestamp.
- Return type
Calculates a
TAI64Time
from itsdouble
representation.
-
char *TAI64Time_encode_text(TAI64Time t)
- Parameters
t (
TAI64Time
) – The current timestamp.
- Returns
A string containing the encoded text.
- Return type
char*
Encodes a
TAI64Time
value as text.
-
TAI64Time TAI64Time_decode_text(char *in)
- Parameters
in (
char*
) – A string containing the encoded text.
- Returns
The decoded timestamp.
- Return type
Decodes a
TAI64Time
value from text.