Module: SolarTerms24::Horizons
- Defined in:
- lib/solar_terms_24/horizons.rb
Overview
:nodoc:
Constant Summary collapse
- TIME_FORMAT =
'%Y-%m-%d %H:%M:%S.%L'
- SOLAR_TERMS =
{ minor_cold: { month: 1, days: 5..7, longitude: 285 }, major_cold: { month: 1, days: 19..21, longitude: 300 }, start_of_spring: { month: 2, days: 3..5, longitude: 315 }, spring_showers: { month: 2, days: 18..20, longitude: 330 }, awakening_of_insects: { month: 3, days: 5..7, longitude: 345 }, spring_equinox: { month: 3, days: 20..22, longitude: 0 }, pure_brightness: { month: 4, days: 4..6, longitude: 15 }, grain_rain: { month: 4, days: 19..21, longitude: 30 }, start_of_summer: { month: 5, days: 5..7, longitude: 45 }, grain_buds: { month: 5, days: 20..22, longitude: 60 }, grain_in_ear: { month: 6, days: 5..7, longitude: 75 }, summer_solstice: { month: 6, days: 20..22, longitude: 90 }, minor_heat: { month: 7, days: 6..8, longitude: 105 }, major_heat: { month: 7, days: 22..24, longitude: 120 }, start_of_autumn: { month: 8, days: 7..9, longitude: 135 }, end_of_heat: { month: 8, days: 22..24, longitude: 150 }, white_dew: { month: 9, days: 7..9, longitude: 165 }, autumn_equinox: { month: 9, days: 22..24, longitude: 180 }, cold_dew: { month: 10, days: 7..9, longitude: 195 }, frost: { month: 10, days: 22..24, longitude: 210 }, start_of_winter: { month: 11, days: 7..9, longitude: 225 }, minor_snow: { month: 11, days: 21..23, longitude: 240 }, major_snow: { month: 12, days: 6..8, longitude: 255 }, winter_solstice: { month: 12, days: 21..23, longitude: 270 } }.freeze
Class Method Summary collapse
- .fetch_ecliptic_longitudes(start_time, end_time, step:) ⇒ Object
- .find_solar_terms_times(year) ⇒ Object
- .range_index(data, longitude) ⇒ Object
Class Method Details
.fetch_ecliptic_longitudes(start_time, end_time, step:) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/solar_terms_24/horizons.rb', line 61 def fetch_ecliptic_longitudes(start_time, end_time, step:) response = Faraday.get('https://ssd.jpl.nasa.gov/api/horizons.api', { format: 'text', COMMAND: '10', QUANTITIES: '31', START_TIME: "'#{start_time.strftime(TIME_FORMAT)}'", STOP_TIME: "'#{end_time.strftime(TIME_FORMAT)}'", STEP_SIZE: "'#{step}'" }) lines = response.body.split("\n") lines[lines.index('$$SOE') + 1..lines.index('$$EOE') - 1].map do |line| # regex matches the time and ecliptic longitude matches = line.match(/(\d+-\w+-\d{2} \d{2}:\d{2}|\d+-\w+-\d{2} \d{2}:\d{2}:\d{2}\.\d{3})\s+([\d.]+)/) { time: matches[1], longitude: matches[2].to_f } end end |
.find_solar_terms_times(year) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/solar_terms_24/horizons.rb', line 37 def find_solar_terms_times(year) whole_year_data = fetch_ecliptic_longitudes(Date.new(year, 1, 5), Date.new(year, 12, 23), step: '1 hour') whole_year_data.sort_by! { |d| d[:longitude] } SOLAR_TERMS.keys.each_with_object({}) do |key, h| range = range_index(whole_year_data, SOLAR_TERMS[key][:longitude]) range = [whole_year_data[range[0]], whole_year_data[range[1]]] # interpolate the time longitude_diff = range[1][:longitude] - range[0][:longitude] longitude_diff += 360 if longitude_diff.negative? target_longitude = SOLAR_TERMS[key][:longitude].zero? ? 360 : SOLAR_TERMS[key][:longitude] ratio = (target_longitude - range[0][:longitude]) / longitude_diff base_time = DateTime.parse(range[0][:time]) h[key] = base_time + 1/24r * ratio.to_r end end |
.range_index(data, longitude) ⇒ Object
54 55 56 57 58 59 |
# File 'lib/solar_terms_24/horizons.rb', line 54 def range_index(data, longitude) return [data.size - 1, 0] if longitude.zero? index = data.bsearch_index { |d| d[:longitude] >= longitude } [index - 1, index] end |