Class: Astronoby::Instant

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/astronoby/instant.rb

Overview

Represents a specific instant in time using Terrestrial Time (TT) as its internal representation. This class provides conversions between different time scales commonly used in astronomy:

  • Terrestrial Time (TT)

  • International Atomic Time (TAI)

  • Universal Time Coordinated (UTC)

  • Greenwich Mean Sidereal Time (GMST)

Examples:

Create an instant from the current time

instant = Astronoby::Instant.from_time(Time.now)
instant.tai  # Get International Atomic Time

Create an instant from Terrestrial Time

instant = Astronoby::Instant.from_terrestrial_time(2460000.5)

Constant Summary collapse

DATETIME_JD_EPOCH_ADJUSTMENT =

The adjustment value to align our noon-based Julian Date with the midnight-based epoch required by Ruby’s ‘DateTime.jd` constructor. Our internal time values are standard astronomical Julian Dates, which start at noon. `DateTime.jd` expects a day that starts at the preceding midnight. This constant adds 0.5 days (12 hours) to make the conversion.

0.5

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(terrestrial_time) ⇒ Instant

Initialize a new Instant

Parameters:

  • terrestrial_time (Numeric)

    the Terrestrial Time as Julian Date

Raises:



75
76
77
78
79
80
81
82
83
# File 'lib/astronoby/instant.rb', line 75

def initialize(terrestrial_time)
  unless terrestrial_time.is_a?(Numeric)
    raise UnsupportedFormatError, "terrestrial_time must be a Numeric"
  end

  @terrestrial_time = terrestrial_time
  @memo = {}
  freeze
end

Instance Attribute Details

#terrestrial_timeNumeric (readonly) Also known as: tt, julian_date

Returns the Terrestrial Time as a Julian Date.

Returns:

  • (Numeric)

    the Terrestrial Time as a Julian Date



66
67
68
# File 'lib/astronoby/instant.rb', line 66

def terrestrial_time
  @terrestrial_time
end

Class Method Details

.from_terrestrial_time(terrestrial_time) ⇒ Astronoby::Instant

Creates a new Instant from a Terrestrial Time value

Parameters:

  • terrestrial_time (Numeric)

    the Terrestrial Time as a Julian Date

Returns:

Raises:



38
39
40
# File 'lib/astronoby/instant.rb', line 38

def from_terrestrial_time(terrestrial_time)
  new(terrestrial_time)
end

.from_time(time) ⇒ Astronoby::Instant

Creates a new Instant from a Time object

Parameters:

  • time (Time)

    a Time object to convert

Returns:



46
47
48
49
50
51
# File 'lib/astronoby/instant.rb', line 46

def from_time(time)
  delta_t = Util::Time.terrestrial_universal_time_delta(time)
  terrestrial_time = time.utc.to_datetime.ajd +
    Rational(delta_t, Constants::SECONDS_PER_DAY)
  from_terrestrial_time(terrestrial_time)
end

.from_utc_julian_date(julian_date) ⇒ Astronoby::Instant

Creates a new Instant from a Julian Date in UTC

Parameters:

  • julian_date (Numeric)

    the Julian Date in UTC

Returns:



57
58
59
60
61
62
# File 'lib/astronoby/instant.rb', line 57

def from_utc_julian_date(julian_date)
  delta_t = Util::Time.terrestrial_universal_time_delta(julian_date)
  terrestrial_time = julian_date +
    Rational(delta_t, Constants::SECONDS_PER_DAY)
  from_terrestrial_time(terrestrial_time)
end

Instance Method Details

#<=>(other) ⇒ Integer?

Compare this instant with another

Parameters:

Returns:

  • (Integer, nil)

    -1, 0, 1 for less than, equal to, greater than; nil if other is not an Instant



195
196
197
198
199
# File 'lib/astronoby/instant.rb', line 195

def <=>(other)
  return unless other.is_a?(self.class)

  @terrestrial_time <=> other.terrestrial_time
end

#delta_tNumeric

Get the ΔT (Delta T) value for this instant ΔT is the difference between TT and UT1

Returns:

  • (Numeric)

    Delta T in seconds



122
123
124
125
# File 'lib/astronoby/instant.rb', line 122

def delta_t
  @memo[:delta_t] ||=
    Util::Time.terrestrial_universal_time_delta(@terrestrial_time)
end

#diff(other) ⇒ Numeric

Calculate the time difference between two Instant objects

Parameters:

Returns:

  • (Numeric)

    the difference in days



89
90
91
# File 'lib/astronoby/instant.rb', line 89

def diff(other)
  @terrestrial_time - other.terrestrial_time
end

#gastNumeric

Get the Greenwich Apparent Sidereal Time

Returns:

  • (Numeric)

    the sidereal time in hours



137
138
139
# File 'lib/astronoby/instant.rb', line 137

def gast
  @memo[:gast] ||= GreenwichApparentSiderealTime.from_utc(to_time).time
end

#gmstNumeric

Get the Greenwich Mean Sidereal Time

Returns:

  • (Numeric)

    the sidereal time in hours



130
131
132
# File 'lib/astronoby/instant.rb', line 130

def gmst
  @memo[:gmst] ||= GreenwichMeanSiderealTime.from_utc(to_time).time
end

#hashInteger

Calculate hash value for the instant

Returns:

  • (Integer)

    hash value



186
187
188
# File 'lib/astronoby/instant.rb', line 186

def hash
  [@terrestrial_time, self.class].hash
end

#last(longitude:) ⇒ Numeric

Get the Local Apparent Sidereal Time

Parameters:

Returns:

  • (Numeric)

    the sidereal time in hours



153
154
155
# File 'lib/astronoby/instant.rb', line 153

def last(longitude:)
  LocalApparentSiderealTime.from_utc(to_time, longitude: longitude).time
end

#lmst(longitude:) ⇒ Numeric

Get the Local Mean Sidereal Time

Parameters:

Returns:

  • (Numeric)

    the sidereal time in hours



145
146
147
# File 'lib/astronoby/instant.rb', line 145

def lmst(longitude:)
  LocalMeanSiderealTime.from_utc(to_time, longitude: longitude).time
end

#taiNumeric

Get the International Atomic Time (TAI)

Returns:

  • (Numeric)

    TAI as Julian Date



160
161
162
163
# File 'lib/astronoby/instant.rb', line 160

def tai
  @memo[:tai] ||= @terrestrial_time -
    Rational(Constants::TAI_TT_OFFSET, Constants::SECONDS_PER_DAY)
end

#tdbNumeric

Get the Barycentric Dynamical Time (TDB) Note: Currently approximated as equal to TT

Returns:

  • (Numeric)

    TDB as Julian Date



169
170
171
172
173
174
# File 'lib/astronoby/instant.rb', line 169

def tdb
  # This is technically false, there is a slight difference between TT and
  # TDB. However, this difference is so small that currenly Astronoby
  # doesn't support it and consider they are the same value.
  @memo[:tdb] ||= @terrestrial_time
end

#to_dateDate

Convert to Date (UTC)

Returns:

  • (Date)

    the UTC date



107
108
109
# File 'lib/astronoby/instant.rb', line 107

def to_date
  to_datetime.to_date
end

#to_datetimeDateTime

Convert to DateTime (UTC)

Returns:

  • (DateTime)

    the UTC time as DateTime



96
97
98
99
100
101
102
# File 'lib/astronoby/instant.rb', line 96

def to_datetime
  @memo[:to_datetime] ||= DateTime.jd(
    @terrestrial_time -
      Rational(delta_t, Constants::SECONDS_PER_DAY) +
      DATETIME_JD_EPOCH_ADJUSTMENT
  )
end

#to_timeTime

Convert to Time (UTC)

Returns:

  • (Time)

    the UTC time



114
115
116
# File 'lib/astronoby/instant.rb', line 114

def to_time
  @memo[:to_time] ||= to_datetime.to_time.utc
end

#utc_offsetNumeric

Get the offset between TT and UTC for this instant

Returns:

  • (Numeric)

    the offset in days



179
180
181
# File 'lib/astronoby/instant.rb', line 179

def utc_offset
  Rational(delta_t / Constants::SECONDS_PER_DAY)
end