Class TaiInstant

  • All Implemented Interfaces:
    Serializable, Comparable<TaiInstant>

    public final class TaiInstant
    extends Object
    implements Comparable<TaiInstant>, Serializable
    An instantaneous point on the time-line measured in the TAI time-scale.

    The java.time classes use the Java time-scale for simplicity. That scale works on the assumption that the time-line is simple, there are no leap-seconds and there are always 24 * 60 * 60 seconds in a day. Unfortunately, the Earth's rotation is not straightforward, and a solar day does not match this definition.

    This class is an alternative representation based on the TAI time-scale. TAI is a single incrementing count of SI seconds. There are no leap seconds or other discontinuities.

    As a result of the simple definition, this time-scale would make an excellent timestamp. However, there are, at the time of writing, few easy ways to obtain an accurate TAI instant, but it is relatively easy to obtain a GPS instant. GPS and TAI differ by the fixed amount of 19 seconds.

    The duration between two points on the TAI time-scale is calculated solely using this class. Do not use the between method on Duration as that will lose information. Instead use durationUntil(TaiInstant) on this class.

    It is intended that most applications will use the Instant class which uses the UTC-SLS mapping from UTC to guarantee 86400 seconds per day. Specialist applications with access to an accurate time-source may find this class useful.

    Time-scale

    The TAI time-scale is a very simple well-regarded representation of time. The scale is defined using atomic clocks counting SI seconds. It has proceeded in a continuous uninterrupted manner since the defined epoch of 1958-01-01T00:00:00(TAI). There are no leap seconds or other discontinuities.

    This class may be used for instants in the far past and far future. Since some instants will be prior to 1958, it is not strictly an implementation of TAI. Instead, it is a proleptic time-scale based on TAI and equivalent to it since 1958.

    Implementation Requirements:

    This class is immutable and thread-safe.

    This class must be treated as a value type. Do not synchronize, rely on the identity hash code or use the distinction between equals() and ==.

    See Also:
    Serialized Form
    • Method Detail

      • ofTaiSeconds

        public static TaiInstant ofTaiSeconds​(long taiSeconds,
                                              long nanoAdjustment)
        Obtains an instance of TaiInstant from the number of seconds from the TAI epoch of 1958-01-01T00:00:00(TAI) with a nanosecond fraction of second.

        This method allows an arbitrary number of nanoseconds to be passed in. The factory will alter the values of the second and nanosecond in order to ensure that the stored nanosecond is in the range 0 to 999,999,999. For example, the following will result in the exactly the same instant:

          TaiInstant.ofTaiSeconds(3, 1);
          TaiInstant.ofTaiSeconds(4, -999999999);
          TaiInstant.ofTaiSeconds(2, 1000000001);
         
        Parameters:
        taiSeconds - the number of seconds from the epoch of 1958-01-01T00:00:00(TAI)
        nanoAdjustment - the nanosecond adjustment to the number of seconds, positive or negative
        Returns:
        the TAI instant, not null
        Throws:
        ArithmeticException - if numeric overflow occurs
      • of

        public static TaiInstant of​(Instant instant)
        Obtains an instance of TaiInstant from an Instant.

        Converting a UTC-SLS instant to TAI requires leap second rules. This method uses the latest available system rules. The conversion first maps from UTC-SLS to UTC, then converts to TAI.

        Conversion from an Instant will not be completely accurate near a leap second in accordance with UTC-SLS.

        Parameters:
        instant - the instant to convert, not null
        Returns:
        the TAI instant, not null
        Throws:
        DateTimeException - if the range of TaiInstant is exceeded
        ArithmeticException - if numeric overflow occurs
      • of

        public static TaiInstant of​(UtcInstant instant)
        Obtains an instance of TaiInstant from a UtcInstant.

        Converting a UTC instant to TAI requires leap second rules. This method uses the latest available system rules.

        The TaiInstant will represent exactly the same point on the time-line as per the available leap-second rules. If the leap-second rules change then conversion back to UTC may result in a different instant.

        Parameters:
        instant - the instant to convert, not null
        Returns:
        the TAI instant, not null
        Throws:
        DateTimeException - if the range of TaiInstant is exceeded
        ArithmeticException - if numeric overflow occurs
      • parse

        public static TaiInstant parse​(CharSequence text)
        Obtains an instance of TaiInstant from a text string.

        The following format is accepted:

        • {seconds}.{nanosOfSecond}s(TAI)

        The accepted format is strict. The seconds part must contain only numbers and a possible leading negative sign. The nanoseconds part must contain exactly nine digits. The trailing literal must be exactly specified. This format parses the toString() format.

        Parameters:
        text - the text to parse such as "12345.123456789s(TAI)", not null
        Returns:
        the parsed instant, not null
        Throws:
        DateTimeParseException - if the text cannot be parsed
      • getTaiSeconds

        public long getTaiSeconds()
        Gets the number of seconds from the TAI epoch of 1958-01-01T00:00:00(TAI).

        The TAI second count is a simple incrementing count of seconds where second 0 is 1958-01-01T00:00:00(TAI). The nanosecond part of the second is returned by getNano().

        Returns:
        the seconds from the epoch of 1958-01-01T00:00:00(TAI)
      • withTaiSeconds

        public TaiInstant withTaiSeconds​(long taiSeconds)
        Returns a copy of this TaiInstant with the number of seconds from the TAI epoch of 1958-01-01T00:00:00(TAI).

        The TAI second count is a simple incrementing count of seconds where second 0 is 1958-01-01T00:00:00(TAI). The nanosecond offset of the second is returned by getNano.

        This instance is immutable and unaffected by this method call.

        Parameters:
        taiSeconds - the number of seconds from the epoch of 1958-01-01T00:00:00(TAI)
        Returns:
        a TaiInstant based on this instant with the requested second, not null
      • getNano

        public int getNano()
        Gets the number of nanoseconds, later along the time-line, from the start of the second.

        The nanosecond-of-second value measures the total number of nanoseconds from the second returned by getTaiSeconds().

        Returns:
        the nanoseconds within the second, from 0 to 999,999,999
      • withNano

        public TaiInstant withNano​(int nanoOfSecond)
        Returns a copy of this TaiInstant with the nano-of-second value changed.

        The nanosecond-of-second value measures the total number of nanoseconds from the second returned by getTaiSeconds().

        This instance is immutable and unaffected by this method call.

        Parameters:
        nanoOfSecond - the nano-of-second, from 0 to 999,999,999
        Returns:
        a TaiInstant based on this instant with the requested nano-of-second, not null
        Throws:
        IllegalArgumentException - if nanoOfSecond is out of range
      • plus

        public TaiInstant plus​(Duration duration)
        Returns a copy of this instant with the specified duration added.

        The duration is added using simple addition of the seconds and nanoseconds in the duration to the seconds and nanoseconds of this instant. As a result, the duration is treated as being measured in TAI compatible seconds for the purpose of this method.

        This instance is immutable and unaffected by this method call.

        Parameters:
        duration - the duration to add, not null
        Returns:
        a TaiInstant based on this instant with the duration added, not null
        Throws:
        ArithmeticException - if the calculation exceeds the supported range
      • minus

        public TaiInstant minus​(Duration duration)
        Returns a copy of this instant with the specified duration subtracted.

        The duration is subtracted using simple subtraction of the seconds and nanoseconds in the duration from the seconds and nanoseconds of this instant. As a result, the duration is treated as being measured in TAI compatible seconds for the purpose of this method.

        This instance is immutable and unaffected by this method call.

        Parameters:
        duration - the duration to subtract, not null
        Returns:
        a TaiInstant based on this instant with the duration subtracted, not null
        Throws:
        ArithmeticException - if the calculation exceeds the supported range
      • durationUntil

        public Duration durationUntil​(TaiInstant otherInstant)
        Returns the duration between this instant and the specified instant.

        This calculates the duration between this instant and another based on the TAI time-scale. Adding the duration to this instant using plus(java.time.Duration) will always result in an instant equal to the specified instant.

        Parameters:
        otherInstant - the instant to calculate the duration until, not null
        Returns:
        the duration until the specified instant, may be negative, not null
        Throws:
        ArithmeticException - if the calculation exceeds the supported range
      • toInstant

        public Instant toInstant()
        Converts this instant to an Instant.

        Converting a TAI instant to UTC-SLS requires leap second rules. This method uses the latest available system rules. The conversion first maps from TAI to UTC, then converts to UTC-SLS.

        Conversion to an Instant will not be completely accurate near a leap second in accordance with UTC-SLS.

        Returns:
        an Instant representing the best approximation of this instant, not null
        Throws:
        DateTimeException - if the range of Instant is exceeded
        ArithmeticException - if numeric overflow occurs
      • toUtcInstant

        public UtcInstant toUtcInstant()
        Converts this instant to a UtcInstant.

        Converting a TAI instant to UTC requires leap second rules. This method uses the latest available system rules.

        The UtcInstant will represent exactly the same point on the time-line as per the available leap-second rules. If the leap-second rules change then conversion back to TAI may result in a different instant.

        Returns:
        a UtcInstant representing the same instant, not null
        Throws:
        DateTimeException - if the range of UtcInstant is exceeded
        ArithmeticException - if numeric overflow occurs
      • compareTo

        public int compareTo​(TaiInstant otherInstant)
        Compares this instant to another based on the time-line.
        Specified by:
        compareTo in interface Comparable<TaiInstant>
        Parameters:
        otherInstant - the other instant to compare to, not null
        Returns:
        the comparator value, negative if less, positive if greater
      • isAfter

        public boolean isAfter​(TaiInstant otherInstant)
        Checks if this instant is after the specified instant.

        The comparison is based on the time-line position of the instants.

        Parameters:
        otherInstant - the other instant to compare to, not null
        Returns:
        true if this instant is after the specified instant
        Throws:
        NullPointerException - if otherInstant is null
      • isBefore

        public boolean isBefore​(TaiInstant otherInstant)
        Checks if this instant is before the specified instant.

        The comparison is based on the time-line position of the instants.

        Parameters:
        otherInstant - the other instant to compare to, not null
        Returns:
        true if this instant is before the specified instant
        Throws:
        NullPointerException - if otherInstant is null
      • equals

        public boolean equals​(Object otherInstant)
        Checks if this instant is equal to the specified TaiInstant.
        Overrides:
        equals in class Object
        Parameters:
        otherInstant - the other instant, null returns false
        Returns:
        true if the other instant is equal to this one
      • hashCode

        public int hashCode()
        Returns a hash code for this instant.
        Overrides:
        hashCode in class Object
        Returns:
        a suitable hash code
      • toString

        public String toString()
        A string representation of this instant.

        The string is formatted as {seconds).(nanosOfSecond}s(TAI). At least one second digit will be present. The nanoseconds will always be nine digits.

        Overrides:
        toString in class Object
        Returns:
        a representation of this instant, not null