Class: MarsDateTime
Constant Summary collapse
- VERSION =
"1.0.6"- MSEC_PER_SOL =
88775244- SOLS_PER_MYEAR =
668.5921- MSEC_PER_DAY =
86400000- FAKE_MSEC_PER_MYEAR =
(668*MSEC_PER_SOL)
- TimeStretch =
MSEC_PER_SOL/MSEC_PER_DAY.to_f
- Months =
%w[ UNDEFINED January Gemini February Cancer March Leo April Virgo May Libra June Scorpio July Sagittarius August Capricorn September Aquarius October Pisces November Aries December Taurus ]- Week =
no month 0
%w[ Sunday Monday Tuesday Wednesday Thursday Friday Saturday ]- EpochMCE =
DateTime.new(1,1,21)
- EpochCE =
DateTime.new(1,1,1)
- FudgeOffset =
67784 + 44000 + 1099 + 87 - 56
- JulianDay1 =
was …24
1721443
Instance Attribute Summary collapse
-
#day_of_week ⇒ Object
readonly
Returns the value of attribute day_of_week.
-
#dow ⇒ Object
readonly
Returns the value of attribute dow.
-
#epoch_sol ⇒ Object
readonly
Returns the value of attribute epoch_sol.
-
#mems ⇒ Object
readonly
Returns the value of attribute mems.
-
#mhrs ⇒ Object
(also: #hr)
readonly
Returns the value of attribute mhrs.
-
#mmin ⇒ Object
(also: #min)
readonly
Returns the value of attribute mmin.
-
#month ⇒ Object
readonly
Returns the value of attribute month.
-
#msec ⇒ Object
(also: #sec)
readonly
Returns the value of attribute msec.
-
#shr ⇒ Object
readonly
stretched time.
-
#smin ⇒ Object
readonly
stretched time.
-
#sol ⇒ Object
readonly
Returns the value of attribute sol.
-
#ssec ⇒ Object
readonly
stretched time.
-
#year ⇒ Object
(also: #myear)
readonly
Returns the value of attribute year.
-
#year_sol ⇒ Object
readonly
Returns the value of attribute year_sol.
Class Method Summary collapse
-
.leap?(myear) ⇒ Boolean
class method for convenience.
- .now ⇒ Object
- .sols_in_month(m, year) ⇒ Object
- .today ⇒ Object
Instance Method Summary collapse
- #+(sols) ⇒ Object
- #-(other) ⇒ Object
- #<=>(other) ⇒ Object
- #check_ymshms(my, mm, msol, mhr = 0, mmin = 0, msec = 0) ⇒ Object
- #compute_stretched ⇒ Object
- #earth_date ⇒ Object
- #init_datetime(dt) ⇒ Object
- #init_mems(mems) ⇒ Object
- #init_yms(my, mm, msol, mhr = 0, mmin = 0, msec = 0) ⇒ Object
-
#initialize(*params) ⇒ MarsDateTime
constructor
A new instance of MarsDateTime.
- #inspect ⇒ Object
- #leap?(myear) ⇒ Boolean
- #leaps(myr) ⇒ Object
- #month_name ⇒ Object
- #strftime(fmt) ⇒ Object
- #to_s ⇒ Object
- #to_yaml_properties ⇒ Object
- #ymshms ⇒ Object
Constructor Details
#initialize(*params) ⇒ MarsDateTime
Returns a new instance of MarsDateTime.
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/marsdate.rb', line 100 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 DateTime init_datetime(params.first) else raise "Expected number or DateTime" end else raise "Bad params: #{params.inspect}" end compute_stretched end |
Instance Attribute Details
#day_of_week ⇒ Object (readonly)
Returns the value of attribute day_of_week.
37 38 39 |
# File 'lib/marsdate.rb', line 37 def day_of_week @day_of_week end |
#dow ⇒ Object (readonly)
Returns the value of attribute dow.
37 38 39 |
# File 'lib/marsdate.rb', line 37 def dow @dow end |
#epoch_sol ⇒ Object (readonly)
Returns the value of attribute epoch_sol.
33 34 35 |
# File 'lib/marsdate.rb', line 33 def epoch_sol @epoch_sol end |
#mems ⇒ Object (readonly)
Returns the value of attribute mems.
35 36 37 |
# File 'lib/marsdate.rb', line 35 def mems @mems end |
#mhrs ⇒ Object (readonly) Also known as: hr
Returns the value of attribute mhrs.
38 39 40 |
# File 'lib/marsdate.rb', line 38 def mhrs @mhrs end |
#mmin ⇒ Object (readonly) Also known as: min
Returns the value of attribute mmin.
38 39 40 |
# File 'lib/marsdate.rb', line 38 def mmin @mmin end |
#month ⇒ Object (readonly)
Returns the value of attribute month.
33 34 35 |
# File 'lib/marsdate.rb', line 33 def month @month end |
#msec ⇒ Object (readonly) Also known as: sec
Returns the value of attribute msec.
38 39 40 |
# File 'lib/marsdate.rb', line 38 def msec @msec end |
#shr ⇒ Object (readonly)
stretched time
34 35 36 |
# File 'lib/marsdate.rb', line 34 def shr @shr end |
#smin ⇒ Object (readonly)
stretched time
34 35 36 |
# File 'lib/marsdate.rb', line 34 def smin @smin end |
#sol ⇒ Object (readonly)
Returns the value of attribute sol.
33 34 35 |
# File 'lib/marsdate.rb', line 33 def sol @sol end |
#ssec ⇒ Object (readonly)
stretched time
34 35 36 |
# File 'lib/marsdate.rb', line 34 def ssec @ssec end |
#year ⇒ Object (readonly) Also known as: myear
Returns the value of attribute year.
33 34 35 |
# File 'lib/marsdate.rb', line 33 def year @year end |
#year_sol ⇒ Object (readonly)
Returns the value of attribute year_sol.
33 34 35 |
# File 'lib/marsdate.rb', line 33 def year_sol @year_sol end |
Class Method Details
.leap?(myear) ⇒ Boolean
class method for convenience
45 46 47 48 49 50 |
# File 'lib/marsdate.rb', line 45 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 |
.now ⇒ Object
58 59 60 61 |
# File 'lib/marsdate.rb', line 58 def self.now d = DateTime.now MarsDateTime.new(d) end |
.sols_in_month(m, year) ⇒ Object
52 53 54 55 56 |
# File 'lib/marsdate.rb', line 52 def self.sols_in_month(m, year) return 28 if m < 24 return 25 if leap?(year) return 24 end |
.today ⇒ Object
63 64 65 66 |
# File 'lib/marsdate.rb', line 63 def self.today d = DateTime.now MarsDateTime.new(d) end |
Instance Method Details
#+(sols) ⇒ Object
224 225 226 227 |
# File 'lib/marsdate.rb', line 224 def +(sols) millisec = sols * MSEC_PER_SOL MarsDateTime.new(@mems + millisec) end |
#-(other) ⇒ Object
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/marsdate.rb', line 208 def -(other) 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 Fixnum, Float self + (-other) else raise "Unexpected data type" end end |
#<=>(other) ⇒ Object
229 230 231 232 233 234 235 236 237 238 |
# File 'lib/marsdate.rb', line 229 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) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/marsdate.rb', line 122 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? Fixnum 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 !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 ⇒ Object
150 151 152 153 154 155 156 157 |
# File 'lib/marsdate.rb', line 150 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 ⇒ Object
240 241 242 243 244 245 246 247 |
# File 'lib/marsdate.rb', line 240 def earth_date secs = @mems/1000 + FudgeOffset 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_datetime(dt) ⇒ Object
197 198 199 200 201 202 |
# File 'lib/marsdate.rb', line 197 def init_datetime(dt) days = dt.jd - JulianDay1 secs = days*86400 + dt.hour*3600 + dt.min*60 + dt.sec secs -= FudgeOffset init_mems(secs*1000) end |
#init_mems(mems) ⇒ Object
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/marsdate.rb', line 159 def init_mems(mems) full_years = 0 loop do millisec = FAKE_MSEC_PER_MYEAR millisec += MSEC_PER_SOL if 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 # # check for leap year... # if mm == 24 # max = leap?(my) ? 25 : 24 # diff = ms - max # if diff > 0 # my, mm, ms = my+1, 1, diff # end # end init_yms(my, mm, ms, mhr, mmin, msec) end |
#init_yms(my, mm, msol, mhr = 0, mmin = 0, msec = 0) ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/marsdate.rb', line 136 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 ⇒ Object
78 79 80 81 82 83 |
# File 'lib/marsdate.rb', line 78 def inspect time = ('%02d' % @mhrs) + ":" + ('%02d' % @mmin) + ":" + ('%02d' % @msec) "#@year/#{'%02d' % @month}/#{'%02d' % @sol} " + "(#@year_sol, #@epoch_sol) #@day_of_week " + time end |
#leap?(myear) ⇒ Boolean
90 91 92 |
# File 'lib/marsdate.rb', line 90 def leap?(myear) MarsDateTime.leap?(myear) # DRY end |
#leaps(myr) ⇒ Object
68 69 70 71 72 |
# File 'lib/marsdate.rb', line 68 def leaps(myr) n = 0 1.upto(myr) {|i| n+=1 if leap?(i) } n end |
#month_name ⇒ Object
94 95 96 |
# File 'lib/marsdate.rb', line 94 def month_name Months[@month] end |
#strftime(fmt) ⇒ Object
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 |
# File 'lib/marsdate.rb', line 249 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_name[0..2] when "%B"; final << month_name when "%d"; final << zsol when "%e"; final << ('%2d' % @sol) when "%F"; final << "#@year-#@month-#@sol" when "%H"; final << zhh when "%j"; final << @year_sol.to_s when "%m"; final << @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 ⇒ Object
85 86 87 88 |
# File 'lib/marsdate.rb', line 85 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 ⇒ Object
74 75 76 |
# File 'lib/marsdate.rb', line 74 def to_yaml_properties %w[@myear @month @sol @epoch_sol @year_sol @dow @day_of_week @msme @mhrs @mmin @msec] end |
#ymshms ⇒ Object
204 205 206 |
# File 'lib/marsdate.rb', line 204 def ymshms [@year, @month, @sol, @mhrs, @mmin, @msec] end |