Class: Horologium::Representations::Civil
- Inherits:
-
Object
- Object
- Horologium::Representations::Civil
- Defined in:
- lib/horologium/representations/civil.rb,
sig/horologium/representations/civil.rbs
Overview
The calendar date and time of day an instant falls on, in the scale it is read in. It is the shape a person reads, where a Julian Date is the shape a series takes.
The calendar is the proleptic Gregorian one, extended backwards past its
1582 introduction, with astronomical year numbering. The conversions are
the ones ERFA performs in eraJd2cal and eraCal2jd, over the range
those routines document, from the year MINIMUM_YEAR on.
The whole conversion runs in exact Rational arithmetic, at both
precisions: a Numeric::TwoPartFloat pair is already an exact Rational,
so nothing is lost on the way in or out, and precision only re-enters
when the fraction of a second is rendered in the type asked for. That
makes it more accurate than eraJd2cal, which does the same work in
double precision, and slower. Reading a civil date is a display step;
the Julian Date and the Duration are what arithmetic runs on.
Constant Summary collapse
- OUTPUTS =
The types the fraction of a second can come out as. A Julian Date's
:two_partis not among them: the fraction is smaller than 1, where the split exists to hold a number too large for one Float. %i[float rational].freeze
- MINIMUM_YEAR =
The earliest year the calendar conversion covers, the range ERFA documents for
eraCal2jd. Every intermediate is non-negative from here on, so Ruby's flooring integer division agrees with the truncating division the C routines are written in. -4799
- MINIMUM_DAY_NUMBER =
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 Julian Day Number of MINIMUM_YEAR-01-01, the earliest day the calendar conversion covers. It bounds the way out as MINIMUM_YEAR bounds the way in, so a reading is never handed back a date that parse would refuse to read.
-31_738
- HALF_DAY =
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.
Half a day, the offset between a Julian Date, which starts at noon, and the day the calendar counts, which starts at midnight.
Rational(1, 2)
- DAYS_IN_MONTH =
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 length of each month in a common year, from January.
[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31].freeze
- SECONDS_PER_HOUR =
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 seconds in an hour.
3_600- SECONDS_PER_MINUTE =
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 seconds in a minute.
60
Class Method Summary collapse
-
.from_fields(year, month, day, hour, minute, second) ⇒ Horologium::Representations::CivilTime
private
A civil time built from the fields as a caller writes them, where the whole second and the fraction under it are one number.
-
.parse(value, _low, scale, precision) ⇒ Horologium::Numeric::TwoPartFloat, Horologium::Numeric::Exact
A civil time as it was given, as a Julian Date in days, at the precision asked for.
-
.render(reading, output) ⇒ Horologium::Representations::CivilTime
The reading, as a calendar date and a time of day.
Class Method Details
.from_fields(year, month, day, hour, minute, second) ⇒ Horologium::Representations::CivilTime
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 civil time built from the fields as a caller writes them, where the whole second and the fraction under it are one number. It is what Instant.from_civil passes to parse.
159 160 161 162 163 |
# File 'lib/horologium/representations/civil.rb', line 159 def from_fields(year, month, day, hour, minute, second) whole, fraction = split_second(second) CivilTime.new(year, month, day, hour, minute, whole, fraction) end |
.parse(value, _low, scale, precision) ⇒ Horologium::Numeric::TwoPartFloat, Horologium::Numeric::Exact
A civil time as it was given, as a Julian Date in days, at the precision asked for. This is the way in, where render is the way out. The Julian Date is in the scale the civil time was read in; it is Instant.from_civil that reads it back in TAI.
Nothing is lost: the date becomes a whole number of days by integer arithmetic, and the time of day an exact fraction of one. A civil time is therefore an exact way to build an instant, where a Julian Date given as a single Float is not.
132 133 134 135 136 137 138 139 140 141 142 |
# File 'lib/horologium/representations/civil.rb', line 132 def parse(value, _low, scale, precision) civil = validate!(value) day = day_number(civil.year, civil.month, civil.day) seconds_in_day = scale.seconds_in_day(day) validate_time!(civil, seconds_in_day) Numeric::Precision.build( day - HALF_DAY + seconds_of_day(civil) / seconds_in_day, precision ) end |
.render(reading, output) ⇒ Horologium::Representations::CivilTime
The reading, as a calendar date and a time of day.
The date and the whole second come from the exact value, whatever the
precision, so they are the fields the instant really falls on. Only
the fraction of a second is rendered in the type asked for: a Float
by default, a Rational under as: :rational, which keeps the whole
of it.
96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/horologium/representations/civil.rb', line 96 def render(reading, output) validate_output!(output) scale = Horologium.configuration.scale(reading.scale) shifted = reading.value.to_r + HALF_DAY day_number = shifted.floor # A leap second makes a UTC day 86,401 seconds long; the scale says # so, and every other scale answers 86,400. seconds_in_day = scale.seconds_in_day(day_number) seconds = (shifted - day_number) * seconds_in_day civil_at(day_number, seconds, seconds_in_day, output) end |