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)
パラメータ
  • calendar (char*) -- The name of the target calendar system.

  • date (char* or long long int or double or TAI64Time) -- The input date.

  • format (char*) -- The format string for parsing the input date.

戻り値

The parsed internal timestamp.

戻り値の型

TAI64Time

Converts an input date/time representation to an internal TAI64Time.

char *Calends_calendar_from_internal(char *calendar, TAI64Time stamp, char *format)
パラメータ
  • 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.

戻り値

The formatted date/time.

戻り値の型

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)
パラメータ
  • calendar (char*) -- The name of the target calendar system.

  • stamp (TAI64Time) -- The internal timestamp value.

  • offset (char* or long long int or double or TAI64Time) -- The input offset.

戻り値

The adjusted internal timestamp.

戻り値の型

TAI64Time

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)
パラメータ

Registers a calendar system class, storing the collected functions as name, and saving defaultFormat for later use while parsing or formatting.

Unregister

void Calends_calendar_unregister(char *name)
パラメータ
  • 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)
パラメータ
  • name (char*) -- The calendar system name to check for.

戻り値

Whether or not the calendar system is currently registered.

戻り値の型

bool

Returns whether or not a calendar system has been registered, yet.

char *Calends_calendar_list_registered()
戻り値

The sorted list of calendar systems currently registered.

戻り値の型

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

注釈

TAI vs UTC

You may have noticed that a TAI64Time object stores times in TAI seconds, not Unix seconds, with a timezone offset of TAI rather than UTC. 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 when 0 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 using TAI64Time_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

Calculations

TAI64Time TAI64Time_add(TAI64Time t, TAI64Time z)
パラメータ
  • t (TAI64Time) -- The current timestamp.

  • z (TAI64Time) -- The timestamp to add to the current one.

戻り値

The sum of the two timestamps.

戻り値の型

TAI64Time

Calculates the sum of two TAI64Time values.

TAI64Time TAI64Time_sub(TAI64Time t, TAI64Time z)
パラメータ
  • t (TAI64Time) -- The current timestamp.

  • z (TAI64Time) -- The timestamp to subtract from the current one.

戻り値

The difference of the two timestamps.

戻り値の型

TAI64Time

Calculates the difference of two TAI64Time values.

Export

char *TAI64Time_string(TAI64Time t)
パラメータ
戻り値

The decimal string representation of the current timestamp.

戻り値の型

char*

Returns the decimal string representation of a TAI64Time value.

TAI64Time TAI64Time_from_string(char *in)
パラメータ
  • in (char*) -- The decimal string representation of a timestamp to calculate.

戻り値

The calculated timestamp.

戻り値の型

TAI64Time

Calculates a TAI64Time from its decimal string representation.

char *TAI64Time_hex_string(TAI64Time t)
パラメータ
戻り値

The hexadecimal string representation of the current timestamp.

戻り値の型

char*

Returns the hexadecimal string representation of a TAI64Time value.

TAI64Time TAI64Time_from_hex_string(char *in)
パラメータ
  • in (char*) -- The hexadecimal string representation of a timestamp to calculate.

戻り値

The calculated timestamp.

戻り値の型

TAI64Time

Calculates a TAI64Time from its hexadecimal string representation.

double TAI64Time_double(TAI64Time t)
パラメータ
戻り値

The arbitrary-precision floating point representation of the current timestamp.

戻り値の型

double

Returns the double representation of a TAI64Time value.

TAI64Time TAI64Time_from_double(double in)
パラメータ
  • in (double) -- The arbitrary-precision floating point representation of a timestamp to calculate.

戻り値

The calculated timestamp.

戻り値の型

TAI64Time

Calculates a TAI64Time from its double representation.

char *TAI64Time_encode_text(TAI64Time t)
パラメータ
戻り値

A string containing the encoded text.

戻り値の型

char*

Encodes a TAI64Time value as text.

TAI64Time TAI64Time_decode_text(char *in)
パラメータ
  • in (char*) -- A string containing the encoded text.

戻り値

The decoded timestamp.

戻り値の型

TAI64Time

Decodes a TAI64Time value from text.

void *TAI64Time_encode_binary(TAI64Time t, int *len)
パラメータ
  • t (TAI64Time) -- The current timestamp.

  • len (int*) -- Will return the length of the binary data.

戻り値

A pointer to the encoded binary data stream.

戻り値の型

void*

Encodes a TAI64Time value as a binary data stream.

TAI64Time TAI64Time_decode_binary(void *in, int len)
パラメータ
  • in (void*) -- A pointer to the encoded binary data stream.

  • len (int) -- The length of the binary data.

戻り値

The decoded timestamp.

戻り値の型

TAI64Time

Decodes a TAI64Time value from a binary data stream.

Helpers

TAI64Time TAI64Time_utc_to_tai(TAI64Time utc)
パラメータ
  • utc (TAI64Time) -- The timestamp to remove the UTC offset from.

戻り値

The calculated timestamp.

戻り値の型

TAI64Time

Removes the UTC leap second offset from a TAI64Time value.

TAI64Time TAI64Time_tai_to_utc(TAI64Time tai)
パラメータ
  • tai (TAI64Time) -- The timestamp to add the UTC offset to.

戻り値

The calculated timestamp.

戻り値の型

TAI64Time

Adds the UTC leap second offset to a TAI64Time value.