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 (CalendarDefinition) ToInternal(date interface{}, format string) (TAI64NARUXTime, error)
- Parametrii
date (
interface{}
) – The input date. Should supportstring
at the very minimum.format (
string
) – The format string for parsing the input date.
- Întoarce
The parsed internal timestamp.
- Tipul întors
- Întoarce
Any error that occurs.
- Tipul întors
error
Converts an input date/time representation to an internal
TAI64NARUXTime
.
- func (CalendarDefinition) FromInternal(stamp TAI64NARUXTime, format string) (string, error)
- Parametrii
stamp (
TAI64NARUXTime
) – The internal timestamp value.format (
string
) – The format string for formatting the output date.
- Întoarce
The formatted date/time.
- Tipul întors
string
- Întoarce
Any error that occurs.
- Tipul întors
error
Converts an internal
TAI64NARUXTime
to a date/time string.
- func (CalendarDefinition) Offset(stamp TAI64NARUXTime, offset interface{}) (TAI64NARUXTime, error)
- Parametrii
stamp (
TAI64NARUXTime
) – The internal timestamp value.offset (
interface{}
) – The input offset. Should supportstring
at the very minimum.
- Întoarce
The adjusted internal timestamp.
- Tipul întors
- Întoarce
Any error that occurs.
- Tipul întors
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)
- Parametrii
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
asname
, and savingdefaultFormat
for later use while parsing or formatting.
- func RegisterElements(name string, toInternal ToInternal, fromInternal FromInternal, offset Offset, defaultFormat string)
- Parametrii
name (
string
) – The name to register the calendar system under.toInternal (
(CalendarDefinition) ToInternal
) – The function for parsing dates into internal timestamps.fromInternal (
(CalendarDefinition) FromInternal
) – The function for formatting internal timestamps as dates.offset (
(CalendarDefinition) Offset
) – The function for adding an offset to internal timestamps.defaultFormat (
string
) – The default format string.
Registers a calendar system from its distinct functions. It does this by storing
toInternal
,fromInternal
, andoffset
as the elements ofname
, and savingdefaultFormat
for later use while parsing or formatting.
Unregister
- func Unregister(name string)
- Parametrii
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
- Parametrii
name (
string
) – The calendar system name to check for.
- Întoarce
Whether or not the calendar system is currently registered.
- Tipul întors
bool
Returns whether or not a calendar system has been registered, yet.
- func ListRegistered() []string
- Întoarce
The sorted list of calendar systems currently registered.
- Tipul întors
[]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.Float
s, 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
- Parametrii
Seconds (
int64
) – The number of TAI seconds sinceCE 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 aTAI64NARUX
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’smath/big.*
values.Notă
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
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 usingTAItoUTC
before generating outputs.- func (TAI64NARUXTime) Add(z TAI64NARUXTime) TAI64NARUXTime
- Parametrii
z (
TAI64NARUXTime
) – The timestamp to add to the current one.
- Întoarce
The sum of the two timestamps.
- Tipul întors
Calculates the sum of two
TAI64NARUXTime
values.
- func (TAI64NARUXTime) Sub(z TAI64NARUXTime) TAI64NARUXTime
- Parametrii
z (
TAI64NARUXTime
) – The timestamp to subtract from the current one.
- Întoarce
The difference of the two timestamps.
- Tipul întors
Calculates the difference of two
TAI64NARUXTime
values.
- func (TAI64NARUXTime) String() string
- Întoarce
The decimal string representation of the current timestamp.
- Tipul întors
string
Returns the decimal string representation of the
TAI64NARUXTime
value.
- func (TAI64NARUXTime) HexString() string
- Întoarce
The hexadecimal string representation of the current timestamp.
- Tipul întors
string
Returns the hexadecimal string representation of the
TAI64NARUXTime
value.
- func (TAI64NARUXTime) Float() Float
- Întoarce
The arbitrary-precision floating point representation of the current timestamp.
- Tipul întors
math/big.(*Float)
Returns the
math/big.(*Float)
representation of theTAI64NARUXTime
value.
- func (TAI64NARUXTime) MarshalText() ([]byte, error)
- Întoarce
A byte slice containing the marshalled text.
- Tipul întors
[]byte
- Întoarce
Any error that occurs.
- Tipul întors
error
Implements the
encoding.TextMarshaler
interface.
- func (TAI64NARUXTime) UnmarshalText(in []byte) error
- Parametrii
in (
[]byte
) – A byte slice containing the marshalled text.
- Întoarce
Any error that occurs.
- Tipul întors
error
Implements the
encoding.TextUnmarshaler
interface.
- func (TAI64NARUXTime) MarshalBinary() ([]byte, error)
- Întoarce
A byte slice containing the marshalled binary data.
- Tipul întors
[]byte
- Întoarce
Any error that occurs.
- Tipul întors
error
Implements the
encoding.BinaryMarshaler
interface.
- func (TAI64NARUXTime) UnmarshalBinary(in []byte) error
- Parametrii
in (
[]byte
) – A byte slice containing the marshalled binary data.
- Întoarce
Any error that occurs.
- Tipul întors
error
Implements the
encoding.BinaryUnmarshaler
interface.
Helpers
- func TAI64NARUXTimeFromDecimalString(in string) TAI64NARUXTime
- Parametrii
in (
string
) – The decimal string representation of a timestamp to calculate.
- Întoarce
The calculated timestamp.
- Tipul întors
Calculates a
TAI64NARUXTime
from its decimal string representation.
- func TAI64NARUXTimeFromHexString(in string) TAI64NARUXTime
- Parametrii
in (
string
) – The hexadecimal string representation of a timestamp to calculate.
- Întoarce
The calculated timestamp.
- Tipul întors
Calculates a
TAI64NARUXTime
from its hexadecimal string representation.
- func TAI64NARUXTimeFromFloat(in Float) TAI64NARUXTime
- Parametrii
in (
math/big.Float
) – The arbitrary-precision floating point representation of a timestamp to calculate.
- Întoarce
The calculated timestamp.
- Tipul întors
Calculates a
TAI64NARUXTime
from itsmath/big.Float
representation.
- func UTCtoTAI(utc TAI64NARUXTime) TAI64NARUXTime
- Parametrii
utc (
TAI64NARUXTime
) – The timestamp to remove the UTC offset from.
- Întoarce
The calculated timestamp.
- Tipul întors
Removes the UTC leap second offset from a TAI64NARUXTime value.
- func TAItoUTC(tai TAI64NARUXTime) TAI64NARUXTime
- Parametrii
tai (
TAI64NARUXTime
) – The timestamp to add the UTC offset to.
- Întoarce
The calculated timestamp.
- Tipul întors
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
- Parametrii
in (
string
) – The name of the unknown calendar system.
- Întoarce
Any error that occurs.
- Tipul întors
error
Generates a „calendar not registered” error, including the calendar’s actual name in the error message.