marsdate 1.1.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +14 -0
- data/LICENSE.txt +21 -0
- data/README.md +650 -0
- data/bin/marsdate +167 -15
- data/lib/marsdate/calendar.rb +128 -0
- data/lib/marsdate/timescale.rb +314 -0
- data/lib/marsdate/version.rb +3 -0
- data/lib/marsdate.rb +289 -241
- data/marsdate.gemspec +31 -0
- data/test/calendar_test.rb +142 -0
- data/test/cli_test.rb +57 -0
- data/test/test.rb +305 -313
- data/test/timescale_test.rb +124 -0
- metadata +51 -19
- data/bin/marsdate-version +0 -5
- data/bin/mcal.rb +0 -50
- data/bin/meh.html +0 -2941
- data/bin/mkcal.rb +0 -51
- data/bin/mtcon.rb +0 -29
- data/bin/mtoday.rb +0 -5
- data/test/spec/marsdate_spec.rb +0 -382
data/test/test.rb
CHANGED
|
@@ -1,377 +1,369 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# MarsDateTime constructors on the official MSD timeline.
|
|
3
|
+
# Run: ruby test/test.rb
|
|
2
4
|
|
|
3
|
-
require 'rubygems'
|
|
4
5
|
require 'minitest/autorun'
|
|
5
|
-
|
|
6
|
-
require '
|
|
6
|
+
require_relative '../lib/marsdate'
|
|
7
|
+
require 'date'
|
|
8
|
+
|
|
9
|
+
class MarsDateTest < Minitest::Test
|
|
10
|
+
def test_civil_ymd_round_trips
|
|
11
|
+
assert_equal [1, 1, 1, 0, 0, 0], MarsDateTime.new(1, 1, 1).ymshms
|
|
12
|
+
assert_equal [2, 3, 4, 0, 0, 0], MarsDateTime.new(2, 3, 4).ymshms
|
|
13
|
+
assert_equal [5, 4, 24, 0, 0, 0], MarsDateTime.new(5, 4, 24).ymshms
|
|
14
|
+
assert_equal [1054, 20, 20, 0, 0, 0], MarsDateTime.new(1054, 20, 20).ymshms
|
|
15
|
+
end
|
|
7
16
|
|
|
8
|
-
|
|
17
|
+
def test_year1_sol1_is_sunday
|
|
18
|
+
assert_equal 0, MarsDateTime.new(1, 1, 1).dow
|
|
19
|
+
assert_equal 'Sunday', MarsDateTime.new(1, 1, 1).day_of_week
|
|
20
|
+
end
|
|
9
21
|
|
|
10
|
-
def
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
end
|
|
15
|
-
assert(expr)
|
|
22
|
+
def test_epoch_msd
|
|
23
|
+
m = MarsDateTime.new(1, 1, 1)
|
|
24
|
+
assert_equal MarsDateTime::EPOCH_MSD, m.msd
|
|
25
|
+
assert_equal 1, m.epoch_sol
|
|
16
26
|
end
|
|
17
27
|
|
|
18
|
-
def
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
assert_equal
|
|
28
|
+
def test_accessors_ymshms_mxt
|
|
29
|
+
m = MarsDateTime.new(1043, 2, 15, 12, 34, 45)
|
|
30
|
+
assert_equal 1043, m.myear
|
|
31
|
+
assert_equal 2, m.month
|
|
32
|
+
assert_equal 15, m.sol
|
|
33
|
+
assert_equal 12, m.mxt_hour
|
|
34
|
+
assert_equal 34, m.mxt_min
|
|
35
|
+
assert_in_delta 45.0, m.mxt_sec, 0.001
|
|
36
|
+
assert_equal 4, m.dow
|
|
37
|
+
assert_equal 'Thursday', m.day_of_week
|
|
38
|
+
assert_equal 43, m.year_sol
|
|
39
|
+
assert_equal 696715, m.epoch_sol
|
|
40
|
+
assert_equal [1043, 2, 15, 12, 34, 45], m.ymshms
|
|
24
41
|
end
|
|
25
42
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
def test_named_constructors
|
|
44
|
+
a = MarsDateTime.new(1043, 2, 15, 12, 34, 45)
|
|
45
|
+
b = MarsDateTime.mxt(1043, 2, 15, 12, 34, 45)
|
|
46
|
+
assert_in_delta 0, a - b, 0
|
|
47
|
+
assert_equal a.msd, MarsDateTime.at(a.msd).msd
|
|
48
|
+
assert_equal a.msd, MarsDateTime.from_msd(a.msd).msd
|
|
49
|
+
|
|
50
|
+
m = MarsDateTime.mtc(1, 1, 1, 15, 46, 58)
|
|
51
|
+
assert_equal 15, m.mtc.hour
|
|
52
|
+
assert_equal 46, m.mtc.min
|
|
53
|
+
assert_in_delta 58.0, m.mtc.sec, 0.5
|
|
54
|
+
assert_equal [1, 1, 1], [m.year, m.month, m.sol]
|
|
36
55
|
end
|
|
37
56
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
57
|
+
def test_mxt_and_mtc_midnight_are_the_same_instant
|
|
58
|
+
a = MarsDateTime.mxt(1077, 23, 6)
|
|
59
|
+
b = MarsDateTime.mtc(1077, 23, 6)
|
|
60
|
+
assert_in_delta 0, a - b, 0
|
|
61
|
+
assert_equal 0, a.mxt.hour
|
|
62
|
+
assert_equal 0, a.mtc.hour
|
|
43
63
|
end
|
|
44
64
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
65
|
+
def test_clock_views
|
|
66
|
+
m = MarsDateTime.mxt(1, 1, 1, 13, 0, 0)
|
|
67
|
+
assert_equal 13, m.mxt.hour
|
|
68
|
+
assert_equal 0, m.mxt.min
|
|
69
|
+
assert_in_delta 0.0, m.mxt.sec, 0.001
|
|
70
|
+
assert_equal :mxt, m.mxt.scale
|
|
71
|
+
assert_equal :mtc, m.mtc.scale
|
|
72
|
+
assert_equal m.format_mxt, m.mxt.to_s
|
|
73
|
+
assert_equal m.format_mtc, m.mtc.to_s
|
|
74
|
+
assert_equal '13', m.format('%H')
|
|
75
|
+
assert_equal '13', m.format_mxt('%H')
|
|
76
|
+
assert_equal '13', m.mxt.format('%H')
|
|
77
|
+
assert_equal '12', m.format_mtc('%H')
|
|
78
|
+
assert_equal '12', m.mtc.format('%H')
|
|
79
|
+
assert_equal 'MXT', m.format('%Z')
|
|
80
|
+
assert_equal 'MXT', m.mxt.format('%Z')
|
|
81
|
+
assert_equal 'MTC', m.format_mtc('%Z')
|
|
82
|
+
assert_equal 'MTC', m.mtc.format('%Z')
|
|
83
|
+
assert_equal '13:00:00 MXT', m.format('%H:%M:%S %Z')
|
|
84
|
+
assert_equal '12:39:07 MTC', m.format_mtc('%H:%M:%S %Z')
|
|
85
|
+
assert_equal m.year, m.mxt.year
|
|
86
|
+
assert_equal m.month_name, m.mtc.month_name
|
|
87
|
+
refute_respond_to m, :strftime
|
|
50
88
|
end
|
|
51
89
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
end
|
|
90
|
+
def test_at_rolls_into_next_sol
|
|
91
|
+
midnight = MarsDateTime.mxt(1, 1, 1)
|
|
92
|
+
nxt = MarsDateTime.at(midnight.msd + 1)
|
|
93
|
+
assert_equal [1, 1, 2], [nxt.year, nxt.month, nxt.sol]
|
|
57
94
|
end
|
|
58
95
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
end
|
|
65
|
-
should "yield a Martian Sunday" do
|
|
66
|
-
assert_equal(md.day_of_week,"Sunday")
|
|
67
|
-
end
|
|
96
|
+
def test_accessors_933
|
|
97
|
+
m = MarsDateTime.new(933, 1, 2)
|
|
98
|
+
assert_equal [933, 1, 2], [m.myear, m.month, m.sol]
|
|
99
|
+
m = MarsDateTime.new(933, 1, 1)
|
|
100
|
+
assert_equal [933, 1, 1], [m.myear, m.month, m.sol]
|
|
68
101
|
end
|
|
69
102
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
end
|
|
103
|
+
def test_taurus_25_leap_only
|
|
104
|
+
assert MarsDateTime.leap?(1067)
|
|
105
|
+
MarsDateTime.new(1067, 24, 25)
|
|
106
|
+
refute MarsDateTime.leap?(1066)
|
|
107
|
+
assert_raises(ArgumentError) { MarsDateTime.new(1066, 24, 25) }
|
|
76
108
|
end
|
|
77
109
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
# my_assert_equal(m.day_of_week,"Friday") { p m }
|
|
84
|
-
end
|
|
110
|
+
def test_reject_invalid_clocks
|
|
111
|
+
assert_raises(ArgumentError) { MarsDateTime.new(1, 1, 1, 24, 40, 0) }
|
|
112
|
+
assert_raises(ArgumentError) { MarsDateTime.mtc(1, 1, 1, 24, 0, 0) }
|
|
113
|
+
assert_raises(ArgumentError) { MarsDateTime.new(1, 1, 1, 25, 0, 0) }
|
|
114
|
+
MarsDateTime.new(1, 1, 1, 24, 39, 35) # last MXT second, ok
|
|
85
115
|
end
|
|
86
116
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
should "set all its accessors properly" do
|
|
90
|
-
assert_equal(1043,m.myear)
|
|
91
|
-
assert_equal(2,m.month)
|
|
92
|
-
assert_equal(15,m.sol)
|
|
93
|
-
assert_equal(12,m.hr)
|
|
94
|
-
assert_equal(34,m.min)
|
|
95
|
-
assert_equal(45,m.sec)
|
|
96
|
-
assert_equal(4,m.dow)
|
|
97
|
-
assert_equal("Thursday",m.day_of_week)
|
|
98
|
-
assert_equal(43,m.year_sol)
|
|
99
|
-
assert_equal(696715,m.epoch_sol)
|
|
100
|
-
end
|
|
117
|
+
def test_earth_before_epoch_rejected
|
|
118
|
+
assert_raises(ArgumentError) { MarsDateTime.new(DateTime.new(1, 1, 22)) }
|
|
101
119
|
end
|
|
102
120
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
m
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
121
|
+
def test_official_mtc_examples
|
|
122
|
+
m = MarsDateTime.new(DateTime.new(2000, 1, 6, 0, 0, 0))
|
|
123
|
+
assert_equal [1063, 19, 21], [m.year, m.month, m.sol]
|
|
124
|
+
assert_equal 23, m.mtc_hour
|
|
125
|
+
assert_equal 59, m.mtc_min
|
|
126
|
+
assert_in_delta 39.3, m.mtc_sec, 1.0
|
|
127
|
+
|
|
128
|
+
m = MarsDateTime.new(DateTime.new(2026, 8, 13, 0, 6, 56))
|
|
129
|
+
assert_equal [1077, 23, 6], [m.year, m.month, m.sol]
|
|
130
|
+
mtc_hours = m.mtc_hour + m.mtc_min / 60.0 + m.mtc_sec / 3600.0
|
|
131
|
+
assert_in_delta 1 + 6 / 60.0 + 22 / 3600.0, mtc_hours, 2.0 / 3600.0
|
|
112
132
|
end
|
|
113
133
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
should "default to today" do
|
|
119
|
-
diff = (e-m2e).abs # m - e doesn't work!
|
|
120
|
-
assert(diff < 1.0)
|
|
121
|
-
end
|
|
134
|
+
def test_offset_independent
|
|
135
|
+
utc = DateTime.new(2000, 1, 1, 12, 0, 0)
|
|
136
|
+
est = utc.new_offset(Rational(-5, 24))
|
|
137
|
+
assert_in_delta MarsDateTime.new(utc).msd, MarsDateTime.new(est).msd, 1e-12
|
|
122
138
|
end
|
|
123
139
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
140
|
+
def test_equinoxes_near_following_new_year
|
|
141
|
+
m = MarsDateTime.new(DateTime.new(2007, 12, 9, 17, 20, 0))
|
|
142
|
+
assert_in_delta 0, MarsDateTime.new(1068, 1, 1) - m, 1.5
|
|
143
|
+
|
|
144
|
+
m = MarsDateTime.new(DateTime.new(1609, 3, 12))
|
|
145
|
+
assert_in_delta 0, MarsDateTime.new(856, 1, 1) - m, 1.5
|
|
146
|
+
|
|
147
|
+
m = MarsDateTime.new(DateTime.new(1902, 8, 12, 7, 0, 0))
|
|
148
|
+
assert_in_delta 0, MarsDateTime.new(1012, 1, 1) - m, 1.5
|
|
131
149
|
end
|
|
132
150
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
should "set the three obvious accessors properly" do
|
|
136
|
-
assert_equal(933,m.myear)
|
|
137
|
-
assert_equal(1,m.month)
|
|
138
|
-
assert_equal(2,m.sol)
|
|
139
|
-
end
|
|
151
|
+
def test_default_constructor_is_now
|
|
152
|
+
assert_in_delta 0, DateTime.now - MarsDateTime.new.earth_date, 1.0
|
|
140
153
|
end
|
|
141
154
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
155
|
+
def test_today_is_current_mars_midnight
|
|
156
|
+
n = MarsDateTime.now
|
|
157
|
+
t = MarsDateTime.today
|
|
158
|
+
assert_equal n.year, t.year
|
|
159
|
+
assert_equal n.month, t.month
|
|
160
|
+
assert_equal n.sol, t.sol
|
|
161
|
+
assert_equal 0, t.mxt_hour
|
|
162
|
+
assert_equal 0, t.mxt_min
|
|
163
|
+
assert_in_delta 0.0, t.mxt_sec, 1e-9
|
|
164
|
+
assert_in_delta 0.0, t.mtc_hour, 1e-9
|
|
165
|
+
assert_operator n.msd - t.msd, :>=, 0
|
|
166
|
+
assert_operator n.msd - t.msd, :<, 1.0
|
|
149
167
|
end
|
|
150
168
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
year = 1066
|
|
161
|
-
should "not exist" do
|
|
162
|
-
assert( ! MarsDateTime.leap?(year) )
|
|
163
|
-
assert_raise(RuntimeError) { MarsDateTime.new(year,24,25) }
|
|
164
|
-
end
|
|
165
|
-
end
|
|
169
|
+
def test_earth_date_of_mars_epoch
|
|
170
|
+
e = MarsDateTime.new(1, 1, 1).earth_date
|
|
171
|
+
assert_equal 1, e.year
|
|
172
|
+
assert_equal 1, e.month
|
|
173
|
+
assert_in_delta 23, e.day, 1
|
|
174
|
+
cap = MarsDateTime.epoch_caption
|
|
175
|
+
assert_equal e.year, cap[:epoch_earth_if_tt_were_ut].year
|
|
176
|
+
assert_equal e.day, cap[:epoch_earth_if_tt_were_ut].day
|
|
177
|
+
assert_match(/TT as UT/, cap[:caveat])
|
|
166
178
|
end
|
|
167
179
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
e = m.earth_date
|
|
172
|
-
assert_equal(1,e.year)
|
|
173
|
-
assert_equal(1,e.month)
|
|
174
|
-
assert((e.day-22).abs <= 1)
|
|
175
|
-
end
|
|
180
|
+
def test_earth_datetime_round_trip
|
|
181
|
+
e = DateTime.new(1902, 8, 12, 7, 0, 0)
|
|
182
|
+
assert_in_delta 0, MarsDateTime.new(e).earth_date - e, 1.0 / 86400.0
|
|
176
183
|
end
|
|
177
184
|
|
|
178
|
-
|
|
179
|
-
e1 = DateTime.new(1961,5,31)
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
e2 = m1.earth_date
|
|
183
|
-
diff = e2 - e1
|
|
184
|
-
assert(diff.abs <= 0.01)
|
|
185
|
-
end
|
|
185
|
+
def test_earth_round_trip
|
|
186
|
+
e1 = DateTime.new(1961, 5, 31)
|
|
187
|
+
e2 = MarsDateTime.new(e1).earth_date
|
|
188
|
+
assert_in_delta 0, e2 - e1, 1.0 / 86400.0
|
|
186
189
|
end
|
|
187
190
|
|
|
188
|
-
|
|
189
|
-
m1 = MarsDateTime.new(1067,1,1)
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
m2 = MarsDateTime.new(e1)
|
|
193
|
-
diff = m2 - m1
|
|
194
|
-
assert(diff.abs < 0.01)
|
|
195
|
-
end
|
|
191
|
+
def test_mars_round_trip
|
|
192
|
+
m1 = MarsDateTime.new(1067, 1, 1)
|
|
193
|
+
m2 = MarsDateTime.new(m1.earth_date)
|
|
194
|
+
assert_in_delta 0, m2 - m1, 1e-8
|
|
196
195
|
end
|
|
197
196
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
assert_equal("Monday",m1.strftime("%A"))
|
|
205
|
-
assert_equal("Aug",m1.strftime("%b"))
|
|
206
|
-
assert_equal("August",m1.strftime("%B"))
|
|
207
|
-
assert_equal("24",m1.strftime("%d"))
|
|
208
|
-
assert_equal("24",m1.strftime("%e"))
|
|
209
|
-
assert_equal("1069-15-24",m1.strftime("%F"))
|
|
210
|
-
assert_equal("416",m1.strftime("%j"))
|
|
211
|
-
assert_equal("15",m1.strftime("%m"))
|
|
212
|
-
assert_equal("0",m1.strftime("%s"))
|
|
213
|
-
assert_equal("2",m1.strftime("%u"))
|
|
214
|
-
assert_equal("60",m1.strftime("%U"))
|
|
215
|
-
assert_equal("1",m1.strftime("%w"))
|
|
216
|
-
assert_equal("1069/15/24",m1.strftime("%x"))
|
|
217
|
-
assert_equal("1069",m1.strftime("%Y"))
|
|
218
|
-
assert_equal("\n",m1.strftime("%n"))
|
|
219
|
-
assert_equal("\t",m1.strftime("%t"))
|
|
220
|
-
assert_equal("%",m1.strftime("%%"))
|
|
221
|
-
|
|
222
|
-
assert_equal("Wed",m2.strftime("%a"))
|
|
223
|
-
assert_equal("Wednesday",m2.strftime("%A"))
|
|
224
|
-
assert_equal("Leo",m2.strftime("%b"))
|
|
225
|
-
assert_equal("Leo",m2.strftime("%B"))
|
|
226
|
-
assert_equal("04",m2.strftime("%d"))
|
|
227
|
-
assert_equal(" 4",m2.strftime("%e"))
|
|
228
|
-
assert_equal("933-6-4",m2.strftime("%F"))
|
|
229
|
-
assert_equal("144",m2.strftime("%j"))
|
|
230
|
-
assert_equal("6",m2.strftime("%m"))
|
|
231
|
-
assert_equal("0",m2.strftime("%s"))
|
|
232
|
-
assert_equal("4",m2.strftime("%u"))
|
|
233
|
-
assert_equal("21",m2.strftime("%U"))
|
|
234
|
-
assert_equal("3",m2.strftime("%w"))
|
|
235
|
-
assert_equal("933/06/04",m2.strftime("%x"))
|
|
236
|
-
assert_equal("933",m2.strftime("%Y"))
|
|
237
|
-
|
|
238
|
-
assert_equal("Sag",m3.strftime("%b"))
|
|
239
|
-
assert_equal("Sagittarius",m3.strftime("%B"))
|
|
197
|
+
def test_earth_round_trip_with_hms
|
|
198
|
+
e1 = DateTime.new(1976, 7, 4, 16, 30, 0)
|
|
199
|
+
30.times do
|
|
200
|
+
e2 = MarsDateTime.new(e1).earth_date
|
|
201
|
+
assert_in_delta 0, e2 - e1, 1.0 / 86400.0
|
|
202
|
+
e1 += 1
|
|
240
203
|
end
|
|
241
204
|
end
|
|
242
205
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
206
|
+
def test_format_dates
|
|
207
|
+
m1 = MarsDateTime.new(1069, 15, 24)
|
|
208
|
+
m2 = MarsDateTime.new(933, 6, 4)
|
|
209
|
+
m3 = MarsDateTime.new(1055, 14, 1)
|
|
210
|
+
|
|
211
|
+
assert_equal 'Mon', m1.format('%a')
|
|
212
|
+
assert_equal 'Monday', m1.format('%A')
|
|
213
|
+
assert_equal 'Aug', m1.format('%b')
|
|
214
|
+
assert_equal 'M-August', m1.format('%B')
|
|
215
|
+
assert_equal '24', m1.format('%d')
|
|
216
|
+
assert_equal '24', m1.format('%e')
|
|
217
|
+
assert_equal '1069-15-24', m1.format('%F')
|
|
218
|
+
assert_equal '416', m1.format('%j')
|
|
219
|
+
assert_equal '15', m1.format('%m')
|
|
220
|
+
assert_equal '0', m1.format('%s')
|
|
221
|
+
assert_equal '2', m1.format('%u')
|
|
222
|
+
assert_equal '60', m1.format('%U')
|
|
223
|
+
assert_equal '1', m1.format('%w')
|
|
224
|
+
assert_equal '1069/15/24', m1.format('%x')
|
|
225
|
+
assert_equal '1069', m1.format('%Y')
|
|
226
|
+
assert_equal "\n", m1.format('%n')
|
|
227
|
+
assert_equal "\t", m1.format('%t')
|
|
228
|
+
assert_equal '%', m1.format('%%')
|
|
229
|
+
|
|
230
|
+
assert_equal 'Wed', m2.format('%a')
|
|
231
|
+
assert_equal 'Wednesday', m2.format('%A')
|
|
232
|
+
assert_equal 'Leo', m2.format('%b')
|
|
233
|
+
assert_equal 'Leo', m2.format('%B')
|
|
234
|
+
assert_equal '04', m2.format('%d')
|
|
235
|
+
assert_equal ' 4', m2.format('%e')
|
|
236
|
+
assert_equal '933-06-04', m2.format('%F')
|
|
237
|
+
assert_equal '144', m2.format('%j')
|
|
238
|
+
assert_equal '06', m2.format('%m')
|
|
239
|
+
assert_equal '0', m2.format('%s')
|
|
240
|
+
assert_equal '4', m2.format('%u')
|
|
241
|
+
assert_equal '21', m2.format('%U')
|
|
242
|
+
assert_equal '3', m2.format('%w')
|
|
243
|
+
assert_equal '933/06/04', m2.format('%x')
|
|
244
|
+
assert_equal '933', m2.format('%Y')
|
|
245
|
+
|
|
246
|
+
assert_equal 'Sag', m3.format('%b')
|
|
247
|
+
assert_equal 'Sagittarius', m3.format('%B')
|
|
248
|
+
|
|
249
|
+
line = '%A, %B %e, %Y %H:%M:%S'
|
|
250
|
+
assert_equal m1.format(line), m1.format_mxt(line)
|
|
251
|
+
assert_equal m1.format(line), m1.mxt.format(line)
|
|
252
|
+
assert_equal m1.format_mtc(line), m1.mtc.format(line)
|
|
255
253
|
end
|
|
256
254
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
should "compare with Earth dates" do
|
|
267
|
-
assert(m1 > e1)
|
|
268
|
-
assert(m2 < e2)
|
|
269
|
-
end
|
|
270
|
-
should "honor equality (within roundoff)" do
|
|
271
|
-
assert(m1 == m1)
|
|
272
|
-
assert(m1 != m2)
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
context "The 'now' and 'today' class methods" do
|
|
277
|
-
t1 = MarsDateTime.now
|
|
278
|
-
t0 = MarsDateTime.today
|
|
279
|
-
should "be less than a day apart" do
|
|
280
|
-
diff = t1 - t0
|
|
281
|
-
assert(diff < 1.0)
|
|
282
|
-
end
|
|
255
|
+
def test_format_clocks_at_midnight
|
|
256
|
+
m = MarsDateTime.new(1, 1, 1)
|
|
257
|
+
assert_equal '00', m.format('%H')
|
|
258
|
+
assert_equal '00', m.format_mtc('%H')
|
|
259
|
+
assert_equal '00:00:00', m.format('%X')
|
|
260
|
+
assert_equal '%P', m.format('%P')
|
|
261
|
+
assert_equal 'foo%', m.format('foo%')
|
|
262
|
+
assert_equal '%', m.format('%')
|
|
263
|
+
assert_equal 'x%', m.format('x%%')
|
|
283
264
|
end
|
|
284
265
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
266
|
+
def test_mtc_just_before_midnight_stays_on_previous_sol
|
|
267
|
+
next_midnight = (MarsDateTime::EPOCH_MSD + 11).to_f
|
|
268
|
+
m = MarsDateTime.at(next_midnight.prev_float)
|
|
269
|
+
|
|
270
|
+
assert_equal [1, 1, 11], [m.year, m.month, m.sol]
|
|
271
|
+
assert_equal [23, 59], [m.mtc_hour, m.mtc_min]
|
|
272
|
+
assert_operator m.mtc_sec, :<, 60
|
|
273
|
+
assert_equal '23:59:59.999', m.format_mtc
|
|
274
|
+
assert_equal '23:59:59 MTC', m.format_mtc('%H:%M:%S %Z')
|
|
290
275
|
end
|
|
291
276
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
m = MarsDateTime.new(
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
assert(m.month == 7)
|
|
298
|
-
assert(m.sol == 10)
|
|
299
|
-
end
|
|
300
|
-
should "give a Martian Saturday" do
|
|
301
|
-
assert(m.day_of_week == "Saturday")
|
|
302
|
-
end
|
|
277
|
+
def test_date_is_a_valid_operand
|
|
278
|
+
d = Date.new(2010, 1, 1)
|
|
279
|
+
m = MarsDateTime.new(d)
|
|
280
|
+
assert_in_delta 0, m - d, 1e-9
|
|
281
|
+
assert_equal 0, m <=> d
|
|
303
282
|
end
|
|
304
283
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
m11 = MarsDateTime.new(856,1,1)
|
|
309
|
-
should "fall on or near 1/1 (MCE)" do
|
|
310
|
-
diff = (m11-m).abs
|
|
311
|
-
assert(diff < 1.5)
|
|
312
|
-
end
|
|
284
|
+
def test_taurus_past_end_is_rejected
|
|
285
|
+
assert_raises(ArgumentError) { MarsDateTime.new(1, 24, 26) }
|
|
286
|
+
assert_raises(ArgumentError) { MarsDateTime.new(1, 24, 28) }
|
|
313
287
|
end
|
|
314
288
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
289
|
+
def test_comparisons
|
|
290
|
+
m1 = MarsDateTime.new(1068, 14, 22)
|
|
291
|
+
m2 = MarsDateTime.new(1068, 14, 21)
|
|
292
|
+
e1 = DateTime.new(2002, 4, 19)
|
|
293
|
+
e2 = DateTime.new(2012, 9, 29)
|
|
294
|
+
assert_operator m1, :>, m2
|
|
295
|
+
assert_operator m2, :<, m1
|
|
296
|
+
assert_operator m1, :>, e1
|
|
297
|
+
assert_operator m2, :<, e2
|
|
298
|
+
assert_equal m1, m1
|
|
299
|
+
refute_equal m1, m2
|
|
323
300
|
end
|
|
324
301
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
m2 = m + 7
|
|
329
|
-
should "be the same day of the week" do
|
|
330
|
-
assert_equal(m.day_of_week, m2.day_of_week)
|
|
331
|
-
end
|
|
332
|
-
end
|
|
333
|
-
context "plus 14 days" do
|
|
334
|
-
m3 = m + 14
|
|
335
|
-
should "be the same day of the week" do
|
|
336
|
-
assert_equal(m.day_of_week, m3.day_of_week)
|
|
337
|
-
end
|
|
338
|
-
end
|
|
339
|
-
context "plus 21 days" do
|
|
340
|
-
m4 = m + 21
|
|
341
|
-
should "be the same day of the week" do
|
|
342
|
-
assert_equal(m.day_of_week, m4.day_of_week)
|
|
343
|
-
end
|
|
302
|
+
def test_year_1043_months_start_thursday
|
|
303
|
+
(1..24).each do |mm|
|
|
304
|
+
assert_equal 'Thursday', MarsDateTime.new(1043, mm, 1).day_of_week
|
|
344
305
|
end
|
|
345
306
|
end
|
|
346
307
|
|
|
347
|
-
|
|
348
|
-
m = MarsDateTime.new(
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
308
|
+
def test_earth_1961_may_31
|
|
309
|
+
m = MarsDateTime.new(DateTime.new(1961, 5, 31))
|
|
310
|
+
assert_equal 1043, m.year
|
|
311
|
+
assert_equal 7, m.month
|
|
312
|
+
assert_equal 8, m.sol
|
|
313
|
+
assert_equal 'Thursday', m.day_of_week
|
|
352
314
|
end
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
m2 = MarsDateTime.new(1062,20,17)
|
|
357
|
-
should "allow subtraction of another date" do
|
|
358
|
-
m = md - m2
|
|
359
|
-
assert( (m - 3.0) < 0.01) # sols
|
|
360
|
-
end
|
|
361
|
-
should "allow subtraction of an Earth date" do
|
|
362
|
-
e = DateTime.new(1998, 3, 12, 16, 45, 0)
|
|
363
|
-
m = md - e
|
|
364
|
-
assert( (m - 3.0) < 0.01) # sols
|
|
365
|
-
end
|
|
366
|
-
should "allow subtraction of a Fixnum" do
|
|
367
|
-
m = md - 3 # sols
|
|
368
|
-
assert( (m - m2) < 0.01)
|
|
369
|
-
end
|
|
370
|
-
should "allow subtraction of a Float" do
|
|
371
|
-
m = md - 3.0 # sols
|
|
372
|
-
assert( (m - m2) < 0.01)
|
|
373
|
-
end
|
|
315
|
+
|
|
316
|
+
def test_martian_april_1_1043_is_thursday
|
|
317
|
+
assert_equal 'Thursday', MarsDateTime.new(1043, 7, 1).day_of_week
|
|
374
318
|
end
|
|
375
319
|
|
|
376
|
-
|
|
320
|
+
def test_plus_weeks_keeps_weekday
|
|
321
|
+
m = MarsDateTime.new(1068, 1, 1)
|
|
322
|
+
assert_equal m.day_of_week, (m + 7).day_of_week
|
|
323
|
+
assert_equal m.day_of_week, (m + 14).day_of_week
|
|
324
|
+
assert_equal m.day_of_week, (m + 21).day_of_week
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
def test_addition_rolls_year
|
|
328
|
+
assert_equal [1067, 1, 1], (MarsDateTime.new(1066, 24, 24) + 1).ymshms[0..2]
|
|
329
|
+
assert_equal [1068, 1, 1], (MarsDateTime.new(1067, 24, 25) + 1).ymshms[0..2]
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def test_subtraction
|
|
333
|
+
md = MarsDateTime.new(1062, 20, 20)
|
|
334
|
+
m2 = MarsDateTime.new(1062, 20, 17)
|
|
335
|
+
assert_in_delta 3.0, md - m2, 1e-9
|
|
336
|
+
assert_in_delta 0, (md - 3) - m2, 1e-9
|
|
337
|
+
assert_in_delta 0, (md - 3.0) - m2, 1e-9
|
|
338
|
+
e = m2.earth_date
|
|
339
|
+
assert_in_delta 3.0, md - e, 1e-8
|
|
340
|
+
d = Date.new(2000, 1, 1)
|
|
341
|
+
dt = DateTime.new(2000, 1, 1, 12, 0, 0)
|
|
342
|
+
assert MarsDateTime.new(dt) - d > 0
|
|
343
|
+
assert_equal 1, MarsDateTime.new(dt) <=> d
|
|
344
|
+
end
|
|
377
345
|
|
|
346
|
+
def test_from_msd_and_json
|
|
347
|
+
m = MarsDateTime.new(1043, 2, 15, 12, 34, 45)
|
|
348
|
+
m2 = MarsDateTime.from_msd(m.msd)
|
|
349
|
+
assert_in_delta 0, m2 - m, 0
|
|
350
|
+
m3 = MarsDateTime.from_json(m.to_json)
|
|
351
|
+
assert_in_delta 0, m3 - m, 0
|
|
352
|
+
assert_equal m.msd, MarsDateTime.new(m.msd).msd
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def test_to_s_labels_both_clocks
|
|
356
|
+
s = MarsDateTime.new(1, 1, 1).to_s
|
|
357
|
+
assert_includes s, 'MXT'
|
|
358
|
+
assert_includes s, 'MTC'
|
|
359
|
+
refute_match(/\bhr\b/, s)
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
def test_no_unmarked_clock_accessors
|
|
363
|
+
m = MarsDateTime.new(1, 1, 1)
|
|
364
|
+
refute m.respond_to?(:hr)
|
|
365
|
+
refute m.respond_to?(:min)
|
|
366
|
+
refute m.respond_to?(:sec)
|
|
367
|
+
assert_raises(ArgumentError) { MarsDateTime.new(1, 1, 1, 0, 0, 0, clock: :mtc) }
|
|
368
|
+
end
|
|
369
|
+
end
|