class MarsDateTime
Constants
- EpochCE
- EpochMCE
- FAKE_MSEC_PER_MYEAR
- JulianDay1
- MSEC_PER_DAY
- MSEC_PER_SOL
- Months
- SOLS_PER_MYEAR
- TimeStretch
- VERSION
- Week
no month 0
Attributes
day_of_week[R]
dow[R]
epoch_sol[R]
hr[R]
mems[R]
mhrs[R]
min[R]
mmin[R]
month[R]
msec[R]
myear[R]
sec[R]
shr[R]
smin[R]
sol[R]
ssec[R]
year[R]
year_sol[R]
Public Class Methods
leap?(myear)
click to toggle source
# File lib/marsdate.rb, line 44 def self.leap?(myear) # class method for convenience return (myear % 2 == 1) if (myear % 10 != 0) return true if (myear % 1000 == 0) return false if (myear % 100 == 0) return true end
long?(myear)
click to toggle source
# File lib/marsdate.rb, line 55 def self.long?(myear) # long year leap?(myear) end
new(*params)
click to toggle source
# File lib/marsdate.rb, line 115 def initialize(*params) n = params.size case n when 3..6 init_yms(*params) when 0 init_datetime(DateTime.now) when 1 case params.first when Integer, Float init_mems(params.first) when Date init_date(params.first) when DateTime init_datetime(params.first) else raise "Expected number or DateTime" end else raise "Bad params: #{params.inspect}" end compute_stretched end
now()
click to toggle source
# File lib/marsdate.rb, line 65 def self.now d = DateTime.now MarsDateTime.new(d) end
short?(myear)
click to toggle source
# File lib/marsdate.rb, line 51 def self.short?(myear) # short year !leap?(myear) end
sols_in_month(m, year)
click to toggle source
# File lib/marsdate.rb, line 59 def self.sols_in_month(m, year) return 28 if m < 24 return 25 if leap?(year) return 24 end
today()
click to toggle source
# File lib/marsdate.rb, line 70 def self.today d = Date.today MarsDateTime.new(d) end
Public Instance Methods
+(sols)
click to toggle source
# File lib/marsdate.rb, line 241 def +(sols) # FIXME? sols or secs? millisec = sols * MSEC_PER_SOL MarsDateTime.new(@mems + millisec) end
-(other)
click to toggle source
# File lib/marsdate.rb, line 225 def -(other) # FIXME? sols or secs? case other when MarsDateTime diff = @mems - other.mems diff.to_f / MSEC_PER_SOL when DateTime other = MarsDateTime.new(other) diff = @mems - other.mems diff.to_f / MSEC_PER_SOL when Integer, Float self + (-other) else raise "Unexpected data type" end end
<=>(other)
click to toggle source
# File lib/marsdate.rb, line 246 def <=>(other) case other when MarsDateTime @mems <=> other.mems when DateTime @mems <=> MarsDateTime.new(other).mems else raise "Invalid comparison" end end
check_ymshms(my, mm, msol, mhr=0, mmin=0, msec=0)
click to toggle source
# File lib/marsdate.rb, line 139 def check_ymshms(my, mm, msol, mhr=0, mmin=0, msec=0) text = "" text << "year #{my} is not an integer\n" unless my.is_a? Integer text << "month #{mm} is out of range" unless (1..24).include? mm text << "sol #{msol} is out of range" unless (1..28).include? msol text << "hour #{mhr} is out of range" unless (0..24).include? mhr text << "minute #{mmin} is out of range" unless (0..59).include? mmin text << "second #{msec} is out of range" unless (0..59).include? msec if !MarsDateTime.leap?(my) && mm == 24 && msol > 24 text << "sol #{msol} is invalid in a non-leap year" end raise text unless text.empty? end
compute_stretched()
click to toggle source
# File lib/marsdate.rb, line 167 def compute_stretched # Handle stretched time... sec = @mhrs*3600 + @mmin*60 + @msec sec /= TimeStretch @shr, sec = sec.divmod(3600) @smin, sec = sec.divmod(60) @ssec = sec.round end
earth_date()
click to toggle source
# File lib/marsdate.rb, line 257 def earth_date secs = @mems/1000 days,secs = secs.divmod(86400) hrs, secs = secs.divmod(3600) min, secs = secs.divmod(60) jday = days + JulianDay1 DateTime.jd(jday, hrs, min, secs) end
init_date(date)
click to toggle source
# File lib/marsdate.rb, line 208 def init_date(date) dt = date.to_datetime days = dt.jd - JulianDay1 secs = days*86400 + dt.hour*3600 + dt.min*60 + dt.sec init_mems(secs*1000) end
init_datetime(dt)
click to toggle source
# File lib/marsdate.rb, line 215 def init_datetime(dt) days = dt.jd - JulianDay1 secs = days*86400 + dt.hour*3600 + dt.min*60 + dt.sec init_mems(secs*1000) end
init_mems(mems)
click to toggle source
# File lib/marsdate.rb, line 176 def init_mems(mems) # Note: The sol length is off by 0.09 msec -- to properly fix this # will require measuring in microseconds so as to avoid floating-point math. # The "round" calls below were experimental and were "mostly" successful. full_years = 0 loop do millisec = FAKE_MSEC_PER_MYEAR millisec += MSEC_PER_SOL if MarsDateTime.leap?(full_years+1) break if mems < millisec mems -= millisec # puts "Subtracting #{millisec} -- one full year => #{mems}" full_years += 1 end mspm = MSEC_PER_SOL*28 full_months,mems = mems.divmod(mspm) full_days, mems = mems.divmod(MSEC_PER_SOL) full_hrs, mems = mems.divmod(3_600_000) full_min, mems = mems.divmod(60_000) sec = mems/1000.0 my = full_years + 1 # 1-based mm = full_months + 1 ms = full_days + 1 mhr = full_hrs # 0-based mmin = full_min msec = sec.to_i frac = sec - msec # fraction of a sec init_yms(my, mm, ms, mhr, mmin, msec) end
init_yms(my, mm, msol, mhr=0, mmin=0, msec=0)
click to toggle source
# File lib/marsdate.rb, line 153 def init_yms(my, mm, msol, mhr=0, mmin=0, msec=0) check_ymshms(my, mm, msol, mhr, mmin, msec) zsol = msol - 1 # z means zero-based zmy = my - 1 # my means Martian year zesol = zmy*668 + leaps(my-1) + (mm-1)*28 + zsol # @mems is "Martian (time since) epoch in milliseconds" @mems = zesol*MSEC_PER_SOL + (mhr*3600 + mmin*60 + msec)*1000 @year, @month, @sol, @mhrs, @mmin, @msec = my, mm, msol, mhr, mmin, msec @epoch_sol = zesol + 1 @dow = (@epoch_sol-1) % 7 @day_of_week = Week[@dow] @year_sol = (mm-1)*28 + msol end
inspect()
click to toggle source
# File lib/marsdate.rb, line 85 def inspect time = ('%02d' % @mhrs) + ":" + ('%02d' % @mmin) + ":" + ('%02d' % @msec) "#@year/#{'%02d' % @month}/#{'%02d' % @sol} " + "(#@year_sol, #@epoch_sol) #@day_of_week " + time end
leap?()
click to toggle source
# File lib/marsdate.rb, line 97 def leap? MarsDateTime.leap?(@year) # DRY end
leaps(myr)
click to toggle source
# File lib/marsdate.rb, line 75 def leaps(myr) n = 0 1.upto(myr) {|i| n+=1 if MarsDateTime.leap?(i) } n end
long?()
click to toggle source
# File lib/marsdate.rb, line 105 def long? leap? end
month_name()
click to toggle source
# File lib/marsdate.rb, line 109 def month_name Months[@month] end
short?()
click to toggle source
# File lib/marsdate.rb, line 101 def short? ! leap? end
strftime(fmt)
click to toggle source
# File lib/marsdate.rb, line 266 def strftime(fmt) str = fmt.dup pieces = str.scan(/(%.|[^%]+)/).flatten final = "" zmonth = '%02d' % @month zsol = '%02d' % @sol zhh = '%02d' % @mhrs # stretched zmm = '%02d' % @mmin zss = '%02d' % @msec zhc = '%02d' % @shr # canonical zmc = '%02d' % @smin zsc = '%02d' % @ssec pieces.each do |piece| case piece when "%a"; final << @day_of_week[0..2] when "%A"; final << @day_of_week when "%b"; final << (@month.odd? ? month_name[2..4] : month_name[0..2]) when "%B"; final << month_name when "%d"; final << zsol when "%e"; final << ('%2d' % @sol) when "%F"; final << "#@year-#{zmonth}-#{zsol}" when "%H"; final << zhh when "%j"; final << @year_sol.to_s when "%m"; final << zmonth # @month.to_s when "%M"; final << zmm when "%s"; final << @msec.to_s # was: (@mems*1000).to_i.to_s when "%S"; final << zss when "%u"; final << (@dow + 1).to_s when "%U"; final << (@year_sol/7 + 1).to_s when "%w"; final << @dow.to_s when "%x"; final << "#@year/#{zmonth}/#{zsol}" when "%X"; final << "#{zhh}:#{zmm}:#{zss}" when "%Y"; final << @year.to_s when "%n"; final << "\n" when "%t"; final << "\t" when "%%"; final << "%" when "%P"; final << ("%02d" % @shr) when "%Q"; final << ("%02d" % @smin) when "%R"; final << ("%02d" % @ssec) else final << piece end end final end
to_s()
click to toggle source
# File lib/marsdate.rb, line 92 def to_s time = self.strftime('%H:%M:%S [%P:%Q:%R]') "#@day_of_week, #{Months[@month]} #@sol, #@year at #{time}" end
to_yaml_properties()
click to toggle source
# File lib/marsdate.rb, line 81 def to_yaml_properties %w[@myear @month @sol @epoch_sol @year_sol @dow @day_of_week @msme @mhrs @mmin @msec] end
ymshms()
click to toggle source
# File lib/marsdate.rb, line 221 def ymshms [@year, @month, @sol, @mhrs, @mmin, @msec] end