Skip to content

Commit

Permalink
Add decimal_hour_to_time util (#53)
Browse files Browse the repository at this point in the history
Sometimes, the time of the day is available as a decimal number instead
of the three usual components hours/minutes/seconds.

This new util method enables to convert a time as a decimal number into
an actual `Time` object (in UTC).
  • Loading branch information
rhannequin committed Apr 10, 2024
1 parent f201dc3 commit 92022b9
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/astronoby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
require "astronoby/time/greenwich_sidereal_time"
require "astronoby/time/local_sidereal_time"
require "astronoby/util/astrodynamics"
require "astronoby/util/time"
require "astronoby/util/trigonometry"
require "astronoby/true_obliquity"
require "astronoby/version"
26 changes: 26 additions & 0 deletions lib/astronoby/util/time.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

module Astronoby
module Util
module Time
# @param date [Date]
# @param decimal [Numeric] Hour of the day, in decimal hours
# @return [::Time] Date and time
def self.decimal_hour_to_time(date, decimal)
absolute_hour = decimal.abs
hour = absolute_hour.floor

unless hour.between?(0, 24)
raise IncompatibleArgumentsError, "Hour must be between 0 and 24, got #{hour}"
end

decimal_minute = 60 * (absolute_hour - hour)
absolute_decimal_minute = (60 * (absolute_hour - hour)).abs
minute = decimal_minute.floor
second = 60 * (absolute_decimal_minute - absolute_decimal_minute.floor)

::Time.utc(date.year, date.month, date.day, hour, minute, second).round
end
end
end
end
31 changes: 31 additions & 0 deletions spec/astronoby/util/time_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# frozen_string_literal: true

RSpec.describe Astronoby::Util::Time do
describe "::decimal_hour_to_time" do
it "returns a Time object" do
date = Date.new
decimal = 0

expect(described_class.decimal_hour_to_time(date, decimal)).to be_a Time
end

it "converts a decimal time to a Time format" do
date = Date.new(2024, 3, 14)
decimal = 12.34

time = described_class.decimal_hour_to_time(date, decimal)

expect(time).to eq Time.utc(2024, 3, 14, 12, 20, 24)
end

context "when the decimal time is out of range" do
it "raises an error" do
expect { described_class.decimal_hour_to_time(Date.new, 25) }
.to raise_error(
Astronoby::IncompatibleArgumentsError,
"Hour must be between 0 and 24, got 25"
)
end
end
end
end

0 comments on commit 92022b9

Please sign in to comment.