Class: Horologium::Representations::JulianDate
- Inherits:
-
Object
- Object
- Horologium::Representations::JulianDate
- Defined in:
- lib/horologium/representations/julian_date.rb,
sig/horologium/representations/julian_date.rbs
Overview
The Julian Date: the number of days since noon on 1 January 4713 BC, in the scale it is read in. Astronomy counts time with it, and an ephemeris takes it as input.
An instant is already stored as a Julian Date, so on the way out this representation only picks the type it comes out in. At today's dates a Float keeps the Julian Date to a few tens of microseconds, which is where the other types come in.
Constant Summary collapse
- OUTPUTS =
The types a Julian Date can come out as.
%i[float rational two_part].freeze
- DECIMAL =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
The shape a Julian Date written as a String takes: digits, with an optional sign and an optional decimal fraction. There is no exponent, because a Julian Date is not written with one.
/\A[+-]?\d+(\.\d+)?\z/
Class Method Summary collapse
-
.parse(value, low, _scale, precision) ⇒ Horologium::Numeric::TwoPartFloat, Horologium::Numeric::Exact
A Julian Date as it was given, in days, at the precision asked for.
-
.render(reading, output) ⇒ Float, ...
The Julian Date, in the type asked for.
-
.render_value(value, output) ⇒ Float, ...
private
A value in days, in the type asked for.
Class Method Details
.parse(value, low, _scale, precision) ⇒ Horologium::Numeric::TwoPartFloat, Horologium::Numeric::Exact
A Julian Date as it was given, in days, at the precision asked for. This is the way in, where render is the way out. The value is a Julian Date in a scale, not in TAI; it is Instant.from_julian_date that reads it back in TAI.
The lossless shapes come first. A String and a Rational say the Julian Date exactly, and a high and a low Float say it to about twice what one Float holds. A single Float is the lossy one: seven of its sixteen digits go to the day count, which leaves the fraction of a day about 40 microseconds. Horologium stores it faithfully and does not guess, but the loss happened in the literal, before the library was reached.
At :standard two Floats are normalized onto the integer-day grid,
and a String or a Rational is split so that the two Floats carry as
much of it as they can hold. At :exact nothing is dropped, beyond
what the input had already lost.
100 101 102 103 104 |
# File 'lib/horologium/representations/julian_date.rb', line 100 def parse(value, low, _scale, precision) return two_parts(value, low, precision) unless low.nil? single(value, precision) end |
.render(reading, output) ⇒ Float, ...
The Julian Date, in the type asked for.
:float is the default. A Float spends most of its digits on the
Julian Date itself, and at today's dates the numbers it can hold are
about 40 microseconds apart, which is enough to display, to plot, or
to compare at millisecond tolerance. :rational keeps the whole
value. :two_part gives the two parts, to pass to a foreign kernel
that reads them, such as an ERFA binding or a Chebyshev ephemeris
segment. They are only guaranteed to add up to the Julian Date: an
instant is built on the integer-day grid, but a scale conversion
moves the parts off it. For arithmetic, use Duration.
An :exact reading asked for :two_part is split again, and loses
the precision the Rational held beyond the two parts. It only
happens when the caller asks for it.
58 59 60 |
# File 'lib/horologium/representations/julian_date.rb', line 58 def render(reading, output) render_value(reading.value, output) end |
.render_value(value, output) ⇒ Float, ...
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
A value in days, in the type asked for. render reads the value off the reading; a representation that shifts the value before rendering it, such as ModifiedJulianDate, hands the shifted value here.
117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/horologium/representations/julian_date.rb', line 117 def render_value(value, output) case output when :float value.to_f when :rational value.to_r when :two_part two_part(value) else raise UnknownOutputError.new(output, OUTPUTS) end end |