Custom Calendars in Golang

Adding new calendars to Calends is a fairly straightforward process. Implement one interface, or its three methods as standalone functions, and then simply pass them to one of the two registration functions.

Define

The interface in question looks like this:

CalendarDefinition
func (CalendarDefinitionToInternal(date interface{}, format string) (TAI64NARUXTime, error)
Parámetros
  • date (interface{}) – The input date. Should support string at the very minimum.

  • format (string) – The format string for parsing the input date.

Devuelve

The parsed internal timestamp.

Tipo del valor devuelto

TAI64NARUXTime

Devuelve

Any error that occurs.

Tipo del valor devuelto

error

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

func (CalendarDefinitionFromInternal(stamp TAI64NARUXTime, format string) (string, error)
Parámetros
  • stamp (TAI64NARUXTime) – The internal timestamp value.

  • format (string) – The format string for formatting the output date.

Devuelve

The formatted date/time.

Tipo del valor devuelto

string

Devuelve

Any error that occurs.

Tipo del valor devuelto

error

Converts an internal TAI64NARUXTime to a date/time string.

func (CalendarDefinitionOffset(stamp TAI64NARUXTime, offset interface{}) (TAI64NARUXTime, error)
Parámetros
  • stamp (TAI64NARUXTime) – The internal timestamp value.

  • offset (interface{}) – The input offset. Should support string at the very minimum.

Devuelve

The adjusted internal timestamp.

Tipo del valor devuelto

TAI64NARUXTime

Devuelve

Any error that occurs.

Tipo del valor devuelto

error

Adds the given offset to an internal TAI64NARUXTime.

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 one of the following two functions:

func RegisterObject(name string, definition CalendarDefinition, defaultFormat string)
Parámetros
  • name (string) – The name to register the calendar system under.

  • definition (CalendarDefinition) – The calendar system itself.

  • defaultFormat (string) – The default format string.

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

func RegisterElements(name string, toInternal ToInternal, fromInternal FromInternal, offset Offset, defaultFormat string)
Parámetros

Registers a calendar system from its distinct functions. It does this by storing toInternal, fromInternal, and offset as the elements of name, and saving defaultFormat for later use while parsing or formatting.

Unregister

func Unregister(name string)
Parámetros
  • name (string) – The name of the calendar system to remove.

Removes a calendar system from the callback list.

Check and List

func Registered(calendar string) bool
Parámetros
  • name (string) – The calendar system name to check for.

Devuelve

Whether or not the calendar system is currently registered.

Tipo del valor devuelto

bool

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

func ListRegistered() []string
Devuelve

The sorted list of calendar systems currently registered.

Tipo del valor devuelto

[]string

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 TAI64NARUXTime object 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 methods 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 arbitrary-precision floating point math/big.Floats, 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 string or math/big.Float, the rest is handled entirely by these helpers in the library itself.

TAI64NARUXTime
Parámetros
  • Seconds (int64) – The number of TAI seconds since CE 1970-01-01 00:00:00 TAI.

  • Nano (uint32) – The first 9 digits of the timestamp’s fractional component.

  • Atto (uint32) – The 10th through 18th digits of the fractional component.

  • Ronto (uint32) – The 19th through 27th digits of the fractional component.

  • Udecto (uint32) – The 28th through 36th digits of the fractional component.

  • Xindecto (uint32) – The 37th through 45th digits of the fractional component.

TAI64NARUXTime stores a TAI64NARUX instant in a reliable, easily-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 Golang’s math/big.* values.

Nota

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 UTCtoTAI 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 TAItoUTC before generating outputs.

func (TAI64NARUXTimeAdd(TAI64NARUXTime) TAI64NARUXTime
Parámetros
Devuelve

The sum of the two timestamps.

Tipo del valor devuelto

TAI64NARUXTime

Calculates the sum of two TAI64NARUXTime values.

func (TAI64NARUXTimeSub(TAI64NARUXTime) TAI64NARUXTime
Parámetros
  • z (TAI64NARUXTime) – The timestamp to subtract from the current one.

Devuelve

The difference of the two timestamps.

Tipo del valor devuelto

TAI64NARUXTime

Calculates the difference of two TAI64NARUXTime values.

func (TAI64NARUXTimeString() string
Devuelve

The decimal string representation of the current timestamp.

Tipo del valor devuelto

string

Returns the decimal string representation of the TAI64NARUXTime value.

func (TAI64NARUXTimeHexString() string
Devuelve

The hexadecimal string representation of the current timestamp.

Tipo del valor devuelto

string

Returns the hexadecimal string representation of the TAI64NARUXTime value.

func (TAI64NARUXTimeFloat() Float
Devuelve

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

Tipo del valor devuelto

math/big.(*Float)

Returns the math/big.(*Float) representation of the TAI64NARUXTime value.

func (TAI64NARUXTimeMarshalText(([]byte, error)
Devuelve

A byte slice containing the marshalled text.

Tipo del valor devuelto

[]byte

Devuelve

Any error that occurs.

Tipo del valor devuelto

error

Implements the encoding.TextMarshaler interface.

func (TAI64NARUXTimeUnmarshalText(in []byte) error
Parámetros
  • in ([]byte) – A byte slice containing the marshalled text.

Devuelve

Any error that occurs.

Tipo del valor devuelto

error

Implements the encoding.TextUnmarshaler interface.

func (TAI64NARUXTimeMarshalBinary(([]byte, error)
Devuelve

A byte slice containing the marshalled binary data.

Tipo del valor devuelto

[]byte

Devuelve

Any error that occurs.

Tipo del valor devuelto

error

Implements the encoding.BinaryMarshaler interface.

func (TAI64NARUXTimeUnmarshalBinary(in []byte) error
Parámetros
  • in ([]byte) – A byte slice containing the marshalled binary data.

Devuelve

Any error that occurs.

Tipo del valor devuelto

error

Implements the encoding.BinaryUnmarshaler interface.

Helpers

func TAI64NARUXTimeFromDecimalString(in string) TAI64NARUXTime
Parámetros
  • in (string) – The decimal string representation of a timestamp to calculate.

Devuelve

The calculated timestamp.

Tipo del valor devuelto

TAI64NARUXTime

Calculates a TAI64NARUXTime from its decimal string representation.

func TAI64NARUXTimeFromHexString(in string) TAI64NARUXTime
Parámetros
  • in (string) – The hexadecimal string representation of a timestamp to calculate.

Devuelve

The calculated timestamp.

Tipo del valor devuelto

TAI64NARUXTime

Calculates a TAI64NARUXTime from its hexadecimal string representation.

func TAI64NARUXTimeFromFloat(in Float) TAI64NARUXTime
Parámetros
  • in (math/big.Float) – The arbitrary-precision floating point representation of a timestamp to calculate.

Devuelve

The calculated timestamp.

Tipo del valor devuelto

TAI64NARUXTime

Calculates a TAI64NARUXTime from its math/big.Float representation.

func UTCtoTAI(utc TAI64NARUXTime) TAI64NARUXTime
Parámetros
  • utc (TAI64NARUXTime) – The timestamp to remove the UTC offset from.

Devuelve

The calculated timestamp.

Tipo del valor devuelto

TAI64NARUXTime

Removes the UTC leap second offset from a TAI64NARUXTime value.

func TAItoUTC(tai TAI64NARUXTime) TAI64NARUXTime
Parámetros
Devuelve

The calculated timestamp.

Tipo del valor devuelto

TAI64NARUXTime

Adds the UTC leap second offset to a TAI64NARUXTime value.

Errors

ErrUnsupportedInput

Used to indicate that the input date/time weren’t recognized by the calendar system, or that the data type is incorrect.

ErrInvalidFormat

Indicates that the format string isn’t supported by the calendar system.

func ErrUnknownCalendar(calendar string) error
Parámetros
  • in (string) – The name of the unknown calendar system.

Devuelve

Any error that occurs.

Tipo del valor devuelto

error

Generates a «calendar not registered» error, including the calendar’s actual name in the error message.