Module: Sekki24::TimeScale
- Defined in:
- lib/sekki24/time_scale.rb
Constant Summary collapse
- UNIX_EPOCH_JD =
2_440_587.5- SECONDS_PER_DAY =
86_400.0- OFFSET_PATTERN =
/\A([+-])(\d{2}):(\d{2})\z/
Class Method Summary collapse
- .decimal_year(time) ⇒ Object
- .fixed_offset(timezone) ⇒ Object
- .jd_to_utc(jd) ⇒ Object
- .jde_to_utc(jde) ⇒ Object
- .localize(time, timezone) ⇒ Object
- .timezone_key(timezone) ⇒ Object
- .utc_to_jd(time) ⇒ Object
- .utc_to_jde(time) ⇒ Object
Class Method Details
.decimal_year(time) ⇒ Object
33 34 35 36 37 38 |
# File 'lib/sekki24/time_scale.rb', line 33 def decimal_year(time) utc_time = coerce_time(time).getutc year_start = Time.utc(utc_time.year, 1, 1) next_year = Time.utc(utc_time.year + 1, 1, 1) utc_time.year + ((utc_time - year_start) / (next_year - year_start)) end |
.fixed_offset(timezone) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/sekki24/time_scale.rb', line 59 def fixed_offset(timezone) return validate_offset(timezone) if timezone.is_a?(Integer) return 0 if %w[UTC Z].include?(timezone) if timezone.is_a?(String) match = OFFSET_PATTERN.match(timezone) raise ArgumentError, 'timezone must use the format "+09:00"' unless match sign = match[1] == "+" ? 1 : -1 hours = match[2].to_i minutes = match[3].to_i raise ArgumentError, "timezone offset is out of range" if hours > 23 || minutes > 59 return validate_offset(sign * ((hours * 3600) + (minutes * 60))) end return nil if timezone.respond_to?(:utc_to_local) raise ArgumentError, "timezone must be an offset String, Integer, or timezone object" end |
.jd_to_utc(jd) ⇒ Object
16 17 18 |
# File 'lib/sekki24/time_scale.rb', line 16 def jd_to_utc(jd) Time.at((Float(jd) - UNIX_EPOCH_JD) * SECONDS_PER_DAY).utc end |
.jde_to_utc(jde) ⇒ Object
25 26 27 28 29 30 31 |
# File 'lib/sekki24/time_scale.rb', line 25 def jde_to_utc(jde) utc = jd_to_utc(jde) 2.times do utc = jd_to_utc(Float(jde) - (DeltaT.seconds(decimal_year(utc)) / SECONDS_PER_DAY)) end utc end |
.localize(time, timezone) ⇒ Object
40 41 42 43 44 45 46 47 48 49 |
# File 'lib/sekki24/time_scale.rb', line 40 def localize(time, timezone) utc_time = coerce_time(time).getutc offset = fixed_offset(timezone) return utc_time.getlocal(offset) unless offset.nil? local = timezone.utc_to_local(utc_time) return local if local.is_a?(Time) raise ArgumentError, "timezone utc_to_local must return a Time" end |
.timezone_key(timezone) ⇒ Object
51 52 53 54 55 56 57 |
# File 'lib/sekki24/time_scale.rb', line 51 def timezone_key(timezone) offset = fixed_offset(timezone) return [:offset, offset].freeze unless offset.nil? identifier = timezone.identifier if timezone.respond_to?(:identifier) [:timezone, identifier || timezone.object_id].freeze end |
.utc_to_jd(time) ⇒ Object
11 12 13 14 |
# File 'lib/sekki24/time_scale.rb', line 11 def utc_to_jd(time) utc_time = coerce_time(time).getutc (utc_time.to_r / SECONDS_PER_DAY) + UNIX_EPOCH_JD end |
.utc_to_jde(time) ⇒ Object
20 21 22 23 |
# File 'lib/sekki24/time_scale.rb', line 20 def utc_to_jde(time) utc_time = coerce_time(time).getutc utc_to_jd(utc_time) + (DeltaT.seconds(decimal_year(utc_time)) / SECONDS_PER_DAY) end |