darian_calendar 0.2 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NGFkYjZjZDk2Y2MwYzA4M2NhNDI4MDczYzEzODJiNjI2ZTk4YmJjNw==
4
+ MmY2MWYxMTY4NGFjODBhZjE4MTJjZTljMzQ5NDVkNGNlOGQ5ZDI3NA==
5
5
  data.tar.gz: !binary |-
6
- MmNlMjdmZDQ3ZDk1ZDNmZThmNDM0YjUxY2JhM2U5M2RhOWYyMmJjMQ==
6
+ NTY0MWU1OWUzOWVkNDcyM2EyM2E1OGUyNTZhMmE4ODJjZGQxZDM2NA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MzkyNTQ3NmJlNWUyZTEzMzJhYTUzZjBkODcwMDQ3OWYyYWU4ZmY4M2Y0YTgx
10
- MWNiODg0MGQ1ZDg3YWM3ZTdjNmM2YjQwNTJkM2RkOGI0YWUxZGZmNDBmMGM4
11
- OTcxMTk2M2IwYzI0MWFiN2Q0ZTBjZDNmZTBkNjYxNzQ0MTE0OTU=
9
+ NTI4M2QwYmQzZDY1ZTE3ZmU4MmVkYjE0ODI2OTNiYzcyYTgyMTZiZGI2NjQw
10
+ YzhmNWNiOGEwYzk3N2Q2NTFhM2IwYWNjYzUyZTc0MTg1ZjA2MDdhNDdjYWRl
11
+ YzkxZTQyMGZmYzczYzEwOTcwN2ZlMmQwZDQ4MTE0YjU2ZDhjM2M=
12
12
  data.tar.gz: !binary |-
13
- M2EyMmNhZmNmZGViYWY5ZWFmODEzYTUwNTljODAyMjgxNjQxMDExMTFlOWIx
14
- YzlmNzFiZTllZTExYmRlMGMwMzcwYmEzMDQ5Y2IzNDgyY2YzOTgzYTI5NTJi
15
- Yjg5MzE4OTFkMzAyNDg0YzA4NjgwYjY5YTFlMjQ0YzJmOTgxZGQ=
13
+ YmUxYWIwYTBlNWY4OWYyM2JkZmI0YWFkMzZjODZkZmMxZGQ0MGZiODdhMTEz
14
+ MmYwYTMwMzJlYmQ2MWIzMmVmZmIyMTBkZTg5NzZjZjYzM2Y5ZGIyYTE5ZTFm
15
+ ZDdlNzhjNWJkNGQzODcwNjQ4NDBmZWNhY2E0YTM2MzMzNWZjNWU=
@@ -3,6 +3,6 @@ rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
5
  - 2.1.0
6
- - jruby-19mode
7
- - rbx-2.2.4
6
+ - jruby
7
+ - rbx
8
8
  bundler_args: --without development
@@ -1,12 +1,15 @@
1
- ## 0.2
1
+ ## 1.0
2
+ - JSON support
3
+ - Martian date object
4
+ - Bugfixes
5
+ - Optimizations
2
6
 
7
+ ## 0.2
3
8
  - Documentation with Yard
4
9
  - Minor optimization
5
10
 
6
11
  ## 0.1.0
7
-
8
12
  - Working version of the darian calender converter
9
13
 
10
14
  ## 0.0.1
11
-
12
15
  - Initial release
data/README.md CHANGED
@@ -43,6 +43,9 @@ mars_time = DarianCalendar::Time.from_earth(Time.utc(2012, 10, 15, 16, 50, 0), D
43
43
 
44
44
  mars_time = DarianCalendar::Time.parse_earth('2012-10-15 16:50:00 UTC')
45
45
  mars_time = DarianCalendar::Time.parse_earth('2012-10-15 16:50:00 UTC', DarianCalendar::CalendarTypes::MARTIANA)
46
+
47
+ mars_date = DarianCalendar::Date.today
48
+ mars_date = DarianCalendar::Time.now.to_date
46
49
  ```
47
50
 
48
51
  ```ruby
@@ -89,7 +92,7 @@ bundle exec rspec
89
92
  ```
90
93
 
91
94
  ## Copyright
92
- - _The Darian Calendar Ruby Gem_ is Copyright © 2014 Christian Worreschk, MarSec.
95
+ - _The Darian Calendar Ruby Gem_ is Copyright © 2014 by Christian Worreschk, MarSec.
93
96
  - _The Darian System_ is Copyright © 1986-2005 by Thomas Gangale
94
97
 
95
98
  ## License
@@ -1,5 +1,9 @@
1
1
  # encoding: utf-8
2
2
 
3
+ require 'date'
4
+ require 'time'
5
+ require 'json'
6
+ require 'darian_calendar/date'
3
7
  require 'darian_calendar/time'
4
8
 
5
9
  # This Ruby library converts earth time to mars time and back again. You can choose between 5 variants of the Darian calendar system; Martiana, Defrost, Areosynchronous, Hensel and Aqua.
@@ -7,8 +11,44 @@ require 'darian_calendar/time'
7
11
  # It's based on the JavaScript Converter which was developed by Alan Hensel and Thomas Gangale. (http://pweb.jps.net/~tgangale/mars/converter/calendar_clock.htm)
8
12
  module DarianCalendar
9
13
 
14
+ # Variantes of the Darian calendar system (Different sol and month names)
15
+ module CalendarTypes
16
+ MARTIANA = :martiana
17
+ DEFROST = :defrost
18
+ AREOSYNCHRONOUS = :areosynchronous
19
+ HENSEL = :hensel
20
+ AQUA = :aqua
21
+ end
22
+
23
+ MARS_TO_EARTH_DAYS = 1.027491251
24
+ EPOCH_OFFSET = 587744.77817
25
+ SECONDS_A_DAY = 86400.0
26
+ ROUND_UP_SECOND = 1/SECONDS_A_DAY;
27
+ E_DAYS_TIL_UNIX = 719527.0
28
+
29
+ SOL_NAMES = {
30
+ martiana: ['Sol Solis', 'Sol Lunae', 'Sol Martis', 'Sol Mercurii', 'Sol Jovis', 'Sol Veneris', 'Sol Saturni'],
31
+ defrost: ['Axatisol', 'Benasol', 'Ciposol', 'Domesol', 'Erjasol', 'Fulisol', 'Gavisol'],
32
+ areosynchronous: ['Heliosol', 'Phobosol', 'Deimosol', 'Terrasol', 'Venusol', 'Mercurisol', 'Jovisol']
33
+ }
34
+ MONTH_NAMES = {
35
+ martiana: ['Sagittarius', 'Dhanus', 'Capricornus', 'Makara', 'Aquarius', 'Kumbha', 'Pisces', 'Mina', 'Aries', 'Mesha', 'Taurus', 'Rishabha', 'Gemini', 'Mithuna', 'Cancer', 'Karka', 'Leo', 'Simha', 'Virgo', 'Kanya', 'Libra', 'Tula', 'Scorpius', 'Vrishika'],
36
+ defrost: ['Adir', 'Bora', 'Coan', 'Deti', 'Edal', 'Flo', 'Geor', 'Heliba', 'Idanon', 'Jowani', 'Kireal', 'Larno', 'Medior', 'Neturima', 'Ozulikan', 'Pasurabi', 'Rudiakel', 'Safundo', 'Tiunor', 'Ulasja', 'Vadeun', 'Wakumi', 'Xetual', 'Zungo'],
37
+ hensel: ['Vernalis', 'Duvernalis', 'Trivernalis', 'Quadrivernalis', 'Pentavernalis', 'Hexavernalis', 'Aestas', 'Duestas', 'Triestas', 'Quadrestas', 'Pentestas', 'Hexestas', 'Autumnus', 'Duautumn', 'Triautumn', 'Quadrautumn', 'Pentautumn', 'Hexautumn', 'Unember', 'Duember', 'Triember', 'Quadrember', 'Pentember', 'Hexember']
38
+ }
39
+
10
40
  class << self
11
41
 
42
+ # Returns the total number of martian sols for an earth date or time
43
+ # @param earth_date_time [Date/Time] Earth date or time
44
+ # @return [Float] number of sols
45
+ def sols_from_earth(earth_date_time)
46
+ seconds = earth_date_time.is_a?(::Date) ? earth_date_time.strftime("%s").to_f : earth_date_time.to_f
47
+ days = (seconds / SECONDS_A_DAY) + E_DAYS_TIL_UNIX
48
+ sols = (days - EPOCH_OFFSET) / MARS_TO_EARTH_DAYS
49
+ return sols
50
+ end
51
+
12
52
  # Returns the current mars time. Shortcut for 'DarianCalendar::Time.now'
13
53
  # @param type [DarianCalendar::CalendarTypes] Calendar type
14
54
  # @return [DarianCalendar::Time] current mars time
@@ -16,6 +56,13 @@ module DarianCalendar
16
56
  DarianCalendar::Time.now(type)
17
57
  end
18
58
 
59
+ # Returns the current mars time. Shortcut for 'DarianCalendar::Time.now'
60
+ # @param type [DarianCalendar::CalendarTypes] Calendar type
61
+ # @return [DarianCalendar::Time] current mars time
62
+ def today(type=CalendarTypes::MARTIANA)
63
+ DarianCalendar::Date.today(type)
64
+ end
65
+
19
66
  end
20
67
 
21
68
  end
@@ -0,0 +1,213 @@
1
+ # encoding: utf-8
2
+
3
+ module DarianCalendar
4
+
5
+ # The date is a particular day of a Darian calendar year
6
+ class Date
7
+ include Comparable
8
+
9
+ # @return [Integer] year
10
+ attr_reader :year
11
+ # @return [Integer] month of the year
12
+ attr_reader :month
13
+ # @return [Integer] sol of the month
14
+ attr_reader :sol
15
+ # @return [String] full month name ("Mithuna")
16
+ attr_reader :month_name
17
+ # @return [String] full weeksol name ("Sol Jovis")
18
+ attr_reader :week_sol_name
19
+ # @return [Integer] number of sols since the earth date 0-0-0
20
+ attr_reader :total_sols
21
+ # @return [String] sol of the week
22
+ attr_reader :week_sol
23
+ # @return [Integer] season of the year
24
+ attr_reader :season
25
+ # @return [Integer] sol of the season
26
+ attr_reader :sol_of_season
27
+ # @return [Integer] month of the season
28
+ attr_reader :month_of_season
29
+ # @return [Integer] sol of the year
30
+ attr_reader :sol_of_year
31
+ # @return [String] name of the calendar type ("Martiana")
32
+ attr_reader :calendar_type
33
+
34
+ alias :day :sol
35
+ alias :week_day :week_sol
36
+
37
+ protected
38
+
39
+ def set_attributes(total_sols, type)
40
+ @calendar_type = type.to_s.capitalize
41
+ @total_sols = total_sols
42
+
43
+ sD = (@total_sols / 334296).floor
44
+ doD = (@total_sols - (sD * 334296)).floor
45
+
46
+ sC = 0
47
+ doC = doD
48
+ sC = ((doD - 1) / 66859).floor if doD != 0
49
+ doC -= ((sC * 66859) + 1) if sC != 0
50
+
51
+ sX = 0
52
+ doX = doC
53
+ if sC != 0 # century that does not begin with leap day
54
+ sX = ((doC + 1) / 6686).floor
55
+ doX -= ((sX * 6686) - 1) if sX != 0
56
+ else
57
+ sX = (doC / 6686).floor
58
+ doX -= (sX * 6686) if sX != 0
59
+ end
60
+
61
+ sII = 0
62
+ doII = doX
63
+ if (sC != 0) && (sX == 0) # decade that does not begin with leap day
64
+ sII = (doX / 1337).floor
65
+ doII -= (sII * 1337) if sII != 0
66
+ else # 1338, 1337, 1337, 1337 ...
67
+ sII = ((doX - 1) / 1337) if doX != 0
68
+ doII -= ((sII * 1337) + 1) if sII != 0
69
+ end
70
+
71
+ sI = 0
72
+ doI= doII
73
+ if (sII == 0) && ((sX != 0) || ((sX == 0) && (sC == 0)))
74
+ sI = (doII / 669).floor
75
+ doI -= 669 if sI != 0
76
+ else # 668, 669
77
+ sI = ((doII + 1) / 669).floor
78
+ doI -= 668 if sI != 0
79
+ end
80
+
81
+ @year = (500 * sD) + (100 * sC) + (10 * sX) + (2 * sII) + sI
82
+ @season = case true # 0-3
83
+ when (doI < 167) then 0
84
+ when (doI < 334) then 1
85
+ when (doI < 501) then 2
86
+ else 3
87
+ end
88
+
89
+ @sol_of_season = doI - 167 * @season # 0-167
90
+ @month_of_season = (@sol_of_season / 28).floor # 0-5
91
+ @sol_of_year = doI
92
+
93
+ @month = @month_of_season + (6 * @season) + 1 # 1-24
94
+ @sol = doI - (((@month - 1) * 28) - @season) + 1 # 1-28
95
+ @week_sol = ((@sol - 1) % 7) + 1 # 1-7
96
+
97
+ @week_sol_name = case type
98
+ when DarianCalendar::CalendarTypes::MARTIANA, CalendarTypes::HENSEL then DarianCalendar::SOL_NAMES[:martiana][@week_sol-1]
99
+ when DarianCalendar::CalendarTypes::DEFROST then DarianCalendar::SOL_NAMES[:defrost][@week_sol-1]
100
+ when DarianCalendar::CalendarTypes::AREOSYNCHRONOUS then DarianCalendar::SOL_NAMES[:areosynchronous][@week_sol-1]
101
+ when DarianCalendar::CalendarTypes::AQUA then @week_sol.to_s
102
+ else ''
103
+ end
104
+
105
+ @month_name = case type
106
+ when DarianCalendar::CalendarTypes::MARTIANA then DarianCalendar::MONTH_NAMES[:martiana][@month-1]
107
+ when DarianCalendar::CalendarTypes::DEFROST, DarianCalendar::CalendarTypes::AREOSYNCHRONOUS then DarianCalendar::MONTH_NAMES[:defrost][@month-1]
108
+ when DarianCalendar::CalendarTypes::HENSEL then DarianCalendar::MONTH_NAMES[:hensel][@month-1]
109
+ when DarianCalendar::CalendarTypes::AQUA then @month.to_s
110
+ else ''
111
+ end
112
+ end
113
+
114
+ public
115
+
116
+ # Converts a date object to a mars date object
117
+ # @param earth_date [::Date] Earth date
118
+ # @param type [DarianCalendar::CalendarTypes] Calendar type
119
+ # @return [DarianCalendar::Date] mars date
120
+ def self.from_earth(earth_date, type=DarianCalendar::CalendarTypes::MARTIANA)
121
+ self.new(DarianCalendar.sols_from_earth(earth_date), type)
122
+ end
123
+
124
+ # Parses the given representation of a date, and converts it to a mars date
125
+ # @param string [String] String with a date
126
+ # @param type [DarianCalendar::CalendarTypes] Calendar type
127
+ # @return [DarianCalendar::Date] mars date
128
+ def self.parse_earth(string, type=DarianCalendar::CalendarTypes::MARTIANA)
129
+ self.from_earth(::Date.parse(string), type)
130
+ end
131
+
132
+ # Creates a date object denoting the present mars day.
133
+ # @param type [DarianCalendar::CalendarTypes] Calendar type
134
+ # @return [DarianCalendar::Date] current mars date
135
+ def self.today(type=DarianCalendar::CalendarTypes::MARTIANA)
136
+ self.from_earth(::Date.today, type)
137
+ end
138
+
139
+ # Sets the model attributes from a JSON string. Returns self.
140
+ # @param json [String] JSON string
141
+ # @return [DarianCalendar::Date] mars date
142
+ def self.from_json(string)
143
+ json = JSON::parse(string)
144
+ type = json['calendar_type'].to_s.downcase.to_sym rescue nil
145
+ self.new(json['total_sols'].to_f, type)
146
+ end
147
+
148
+ # Compares two dates and returns -1, zero, 1 or nil. The other should be a mars date object.
149
+ # @param another [DarianCalendar::Date]
150
+ # @return [Integer] Compare result
151
+ def <=>(another)
152
+ @total_sols.floor <=> another.total_sols.floor
153
+ end
154
+
155
+ # Return the number of sols in the given year
156
+ # @return [Integer] Number of sols in the given year
157
+ def sols_in_year
158
+ self.leap? ? 669 : 668
159
+ end
160
+
161
+ # Returns true if the given year is a leap year
162
+ # @return [Boolean] true if the given year is a leap year
163
+ def leap?
164
+ return true if (@year % 500) == 0
165
+ return false if (@year % 100) == 0
166
+ return true if (@year % 10) == 0
167
+ return false if (@year % 2) == 0
168
+ return true
169
+ end
170
+
171
+ # Converts the given mars date to earth date
172
+ # @return [Date] earth date
173
+ def to_earth
174
+ earth_days = (@total_sols * DarianCalendar::MARS_TO_EARTH_DAYS) + DarianCalendar::EPOCH_OFFSET + DarianCalendar::ROUND_UP_SECOND
175
+ earth_seconds = ((earth_days - DarianCalendar::E_DAYS_TIL_UNIX) * DarianCalendar::SECONDS_A_DAY) - 1
176
+ ::Time.at(earth_seconds).to_date
177
+ end
178
+
179
+ # Returns a string in an ISO 8601 format (This method doesn’t use the expanded representations).
180
+ # @return [String] Date as a string in an ISO 8601 format
181
+ def to_s
182
+ sprintf('%d-%02d-%02d', @year, @month, @sol)
183
+ end
184
+
185
+ # Returns a JSON string representing the model.
186
+ # @return Returns a JSON string representing the model.
187
+ def to_json
188
+ self.as_json.to_json
189
+ end
190
+
191
+ # Returns a hash representing the model.
192
+ # @return Returns a hash representing the model.
193
+ def as_json
194
+ json = {}
195
+ self.instance_variables.sort.each do |attr|
196
+ field = attr.to_s.gsub('@', '')
197
+ json[field] = self.send(field)
198
+ end
199
+ return json
200
+ end
201
+
202
+ # Converts a number of martian sols to mars date.
203
+ # @param sols optional [Float] Number of martian sols. Default is the number of sols of the the current date.
204
+ # @param type optional [DarianCalendar::CalendarTypes] calendar type.
205
+ # @return [DarianCalendar::Date] mars date
206
+ def initialize(sols=nil, type=DarianCalendar::CalendarTypes::MARTIANA)
207
+ total_sols = sols.to_f != 0 ? sols.to_f : DarianCalendar.sols_from_earth(::Date.today)
208
+ self.set_attributes(total_sols, type)
209
+ end
210
+
211
+ end
212
+
213
+ end
@@ -2,99 +2,36 @@
2
2
 
3
3
  module DarianCalendar
4
4
 
5
- # Variantes of the Darian calendar system
6
- module CalendarTypes
7
- MARTIANA = :martiana
8
- DEFROST = :defrost
9
- AREOSYNCHRONOUS = :areosynchronous
10
- HENSEL = :hensel
11
- AQUA = :aqua
12
- end
13
-
14
5
  # Timestamp in the Darian calendar system
15
- class Time
16
- include Comparable
6
+ class Time < DarianCalendar::Date
17
7
 
18
- # @return [Integer] year
19
- attr_reader :year
20
- # @return [Integer] month of the year
21
- attr_reader :month
22
- # @return [Integer] sol of the month
23
- attr_reader :sol
24
8
  # @return [Integer] hour of the sol
25
9
  attr_reader :hour
26
10
  # @return [Integer] minute of the hour
27
11
  attr_reader :min
28
12
  # @return [Integer] second of the minute
29
13
  attr_reader :sec
30
- # @return [String] full month name ("Mithuna")
31
- attr_reader :month_name
32
- # @return [String] full weeksol name ("Sol Jovis")
33
- attr_reader :week_sol_name
34
- # @return [Float] number of sols (with hour, minutes and seconds) since the earth date 0-0-0
35
- attr_reader :total_sols
36
- # @return [String] sol of the week
37
- attr_reader :week_sol
38
- # @return [Integer] season of the year
39
- attr_reader :season
40
- # @return [Integer] sol of the season
41
- attr_reader :sol_of_season
42
- # @return [Integer] month of the season
43
- attr_reader :month_of_season
44
- # @return [Integer] sol of the year
45
- attr_reader :sol_of_year
46
- # @return [String] name of the calendar type ("Martiana")
47
- attr_reader :calendar_type
48
-
49
- alias :day :sol
50
- alias :week_day :week_sol
51
-
52
- MARS_TO_EARTH_DAYS = 1.027491251
53
- EPOCH_OFFSET = 587744.77817
54
- SECONDS_A_DAY = 86400.0
55
- ROUND_UP_SECOND = 1/SECONDS_A_DAY;
56
- E_DAYS_TIL_UNIX = 719527.0
57
-
58
- SOL_NAMES = {
59
- martiana: ['Sol Solis', 'Sol Lunae', 'Sol Martis', 'Sol Mercurii', 'Sol Jovis', 'Sol Veneris', 'Sol Saturni'],
60
- defrost: ['Axatisol', 'Benasol', 'Ciposol', 'Domesol', 'Erjasol', 'Fulisol', 'Gavisol'],
61
- areosynchronous: ['Heliosol', 'Phobosol', 'Deimosol', 'Terrasol', 'Venusol', 'Mercurisol', 'Jovisol']
62
- }
63
- MONTH_NAMES = {
64
- martiana: ['Sagittarius', 'Dhanus', 'Capricornus', 'Makara', 'Aquarius', 'Kumbha', 'Pisces', 'Mina', 'Aries', 'Mesha', 'Taurus', 'Rishabha', 'Gemini', 'Mithuna', 'Cancer', 'Karka', 'Leo', 'Simha', 'Virgo', 'Kanya', 'Libra', 'Tula', 'Scorpius', 'Vrishika'],
65
- defrost: ['Adir', 'Bora', 'Coan', 'Deti', 'Edal', 'Flo', 'Geor', 'Heliba', 'Idanon', 'Jowani', 'Kireal', 'Larno', 'Medior', 'Neturima', 'Ozulikan', 'Pasurabi', 'Rudiakel', 'Safundo', 'Tiunor', 'Ulasja', 'Vadeun', 'Wakumi', 'Xetual', 'Zungo'],
66
- hensel: ['Vernalis', 'Duvernalis', 'Trivernalis', 'Quadrivernalis', 'Pentavernalis', 'Hexavernalis', 'Aestas', 'Duestas', 'Triestas', 'Quadrestas', 'Pentestas', 'Hexestas', 'Autumnus', 'Duautumn', 'Triautumn', 'Quadrautumn', 'Pentautumn', 'Hexautumn', 'Unember', 'Duember', 'Triember', 'Quadrember', 'Pentember', 'Hexember']
67
- }
68
-
69
- # Calculates the total number of martian sols for this earth time
70
- # @param earth_time [Time] Earth time
71
- # @return [Integer] number of sols
72
- def self.sols_from_earth_time(earth_time)
73
- days = (earth_time.to_f / SECONDS_A_DAY) + E_DAYS_TIL_UNIX
74
- sols = (days - EPOCH_OFFSET) / MARS_TO_EARTH_DAYS
75
- return sols
76
- end
77
14
 
78
15
  # Converts a time object to a mars time object
79
16
  # @param earth_time [Time] Earth time
80
17
  # @param type [DarianCalendar::CalendarTypes] Calendar type
81
18
  # @return [DarianCalendar::Time] mars time
82
- def self.from_earth(earth_time, type=CalendarTypes::MARTIANA)
83
- self.new(self.sols_from_earth_time(earth_time), type)
19
+ def self.from_earth(earth_time, type=DarianCalendar::CalendarTypes::MARTIANA)
20
+ self.new(DarianCalendar.sols_from_earth(earth_time), type)
84
21
  end
85
22
 
86
23
  # Parses the given representation of date and time, and converts it to mars time
87
24
  # @param string [String] String with date and time
88
25
  # @param type [DarianCalendar::CalendarTypes] Calendar type
89
26
  # @return [DarianCalendar::Time] mars time
90
- def self.parse_earth(string, type=CalendarTypes::MARTIANA)
27
+ def self.parse_earth(string, type=DarianCalendar::CalendarTypes::MARTIANA)
91
28
  self.from_earth(::Time.parse(string), type)
92
29
  end
93
30
 
94
31
  # Returns the current mars time.
95
32
  # @param type [DarianCalendar::CalendarTypes] Calendar type
96
33
  # @return [DarianCalendar::Time] current mars time
97
- def self.now(type=CalendarTypes::MARTIANA)
34
+ def self.now(type=DarianCalendar::CalendarTypes::MARTIANA)
98
35
  self.from_earth(::Time.now, type)
99
36
  end
100
37
 
@@ -105,27 +42,11 @@ module DarianCalendar
105
42
  @total_sols <=> another.total_sols
106
43
  end
107
44
 
108
- # Return the number of sols in the given year
109
- # @return [Integer] Number of sols in the given year
110
- def sols_in_year
111
- self.leap? ? 669 : 668
112
- end
113
-
114
- # Returns true if the given year is a leap year
115
- # @return [Boolean] true if the given year is a leap year
116
- def leap?
117
- return true if (@year % 500) == 0
118
- return false if (@year % 100) == 0
119
- return true if (@year % 10) == 0
120
- return false if (@year % 2) == 0
121
- return true
122
- end
123
-
124
45
  # Converts the given mars time to earth time
125
46
  # @return [Time] earth time
126
47
  def to_earth
127
- earth_days = (@total_sols * MARS_TO_EARTH_DAYS) + EPOCH_OFFSET + ROUND_UP_SECOND
128
- earth_seconds = ((earth_days - E_DAYS_TIL_UNIX) * SECONDS_A_DAY) - 1
48
+ earth_days = (@total_sols * DarianCalendar::MARS_TO_EARTH_DAYS) + DarianCalendar::EPOCH_OFFSET + DarianCalendar::ROUND_UP_SECOND
49
+ earth_seconds = ((earth_days - DarianCalendar::E_DAYS_TIL_UNIX) * DarianCalendar::SECONDS_A_DAY) - 1
129
50
  ::Time.at(earth_seconds)
130
51
  end
131
52
 
@@ -135,83 +56,20 @@ module DarianCalendar
135
56
  sprintf('%d-%02d-%02d %02d:%02d:%02d', @year, @month, @sol, @hour, @min, @sec)
136
57
  end
137
58
 
59
+ # Returns the date of the given mars time
60
+ # @return [DarianCalendar::Date] mars date
61
+ def to_date
62
+ DarianCalendar::Date.new(self.total_sols)
63
+ end
64
+
138
65
  # Converts a number of martian sols to mars time.
139
66
  # @param sols optional [Float] Number of martian sols. Default is the number of sols of the the current time.
140
67
  # @param type optional [DarianCalendar::CalendarTypes] calendar type.
141
68
  # @return [DarianCalendar::Time] mars time
142
- def initialize(sols=nil, type=CalendarTypes::MARTIANA)
143
- @calendar_type = type.to_s.capitalize
144
- @total_sols = sols.to_f != 0 ? sols.to_f : self.sols_from_earth_time(::Time.now)
145
-
146
- sD = (@total_sols / 334296).floor
147
- doD = (@total_sols - (sD * 334296)).floor
148
-
149
- sC = 0
150
- doC = doD
151
- sC = ((doD - 1) / 66859).floor if doD != 0
152
- doC -= ((sC * 66859) + 1) if sC != 0
153
-
154
- sX = 0
155
- doX = doC
156
- if sC != 0 # century that does not begin with leap day
157
- sX = ((doC + 1) / 6686).floor
158
- doX -= ((sX * 6686) - 1) if sX != 0
159
- else
160
- sX = (doC / 6686).floor
161
- doX -= (sX * 6686) if sX != 0
162
- end
163
-
164
- sII = 0
165
- doII = doX
166
- if (sC != 0) && (sX == 0) # decade that does not begin with leap day
167
- sII = (doX / 1337).floor
168
- doII -= (sII * 1337) if sII != 0
169
- else # 1338, 1337, 1337, 1337 ...
170
- sII = ((doX - 1) / 1337) if doX != 0
171
- doII -= ((sII * 1337) + 1) if sII != 0
172
- end
173
-
174
- sI = 0
175
- doI= doII
176
- if (sII == 0) && ((sX != 0) || ((sX == 0) && (sC == 0)))
177
- sI = (doII / 669).floor
178
- doI -= 669 if sI != 0
179
- else # 668, 669
180
- sI = ((doII + 1) / 669).floor
181
- doI -= 668 if sI != 0
182
- end
183
-
184
- @year = (500 * sD) + (100 * sC) + (10 * sX) + (2 * sII) + sI
185
- @season = case true # 0-3
186
- when (doI < 167) then 0
187
- when (doI < 334) then 1
188
- when (doI < 501) then 2
189
- else 3
190
- end
191
-
192
- @sol_of_season = doI - 167 * @season # 0-167
193
- @month_of_season = (@sol_of_season / 28).floor # 0-5
194
- @sol_of_year = doI
195
-
196
- @month = @month_of_season + (6 * @season) + 1 # 1-24
197
- @sol = doI - (((@month - 1) * 28) - @season) + 1 # 1-28
198
- @week_sol = ((@sol - 1) % 7) + 1 # 1-7
199
-
200
- @week_sol_name = case type
201
- when CalendarTypes::MARTIANA, CalendarTypes::HENSEL then SOL_NAMES[:martiana][@week_sol-1]
202
- when CalendarTypes::DEFROST then SOL_NAMES[:defrost][@week_sol-1]
203
- when CalendarTypes::AREOSYNCHRONOUS then SOL_NAMES[:areosynchronous][@week_sol-1]
204
- when CalendarTypes::AQUA then @week_sol.to_s
205
- else ''
206
- end
69
+ def initialize(sols=nil, type=DarianCalendar::CalendarTypes::MARTIANA)
70
+ total_sols = sols.to_f != 0 ? sols.to_f : DarianCalendar.sols_from_earth(::Time.now)
207
71
 
208
- @month_name = case type
209
- when CalendarTypes::MARTIANA then MONTH_NAMES[:martiana][@month-1]
210
- when CalendarTypes::DEFROST, CalendarTypes::AREOSYNCHRONOUS then MONTH_NAMES[:defrost][@month-1]
211
- when CalendarTypes::HENSEL then MONTH_NAMES[:hensel][@month-1]
212
- when CalendarTypes::AQUA then @month.to_s
213
- else ''
214
- end
72
+ self.set_attributes(total_sols, type)
215
73
 
216
74
  partial_sol = @total_sols - @total_sols.floor
217
75
  hour = partial_sol* 24
@@ -1,3 +1,3 @@
1
1
  module DarianCalendar
2
- VERSION = '0.2'
2
+ VERSION = '1.0'
3
3
  end
@@ -6,13 +6,42 @@ describe DarianCalendar do
6
6
 
7
7
  describe 'class methods' do
8
8
 
9
+ #def sols_from_earth(earth_date_time)
10
+ # seconds = earth_date_time.is_a?(::Date) ? earth_date_time.strftime("%s").to_f : earth_date_time.to_f
11
+ # days = (seconds / SECONDS_A_DAY) + E_DAYS_TIL_UNIX
12
+ # sols = (days - EPOCH_OFFSET) / MARS_TO_EARTH_DAYS
13
+ # return sols
14
+ #end
15
+ describe '#sols_from_earth' do
16
+ context 'parameter is a date object' do
17
+ it 'returns the total number of martian sols' do
18
+ earth = ::Date.new(2012, 10, 15)
19
+ DarianCalendar.sols_from_earth(earth).should == 143466.15767923463
20
+ end
21
+ end
22
+ context 'parameter is a time object' do
23
+ it 'returns the total number of martian sols' do
24
+ earth = ::Time.utc(2012, 10, 15, 16, 50, 0)
25
+ DarianCalendar.sols_from_earth(earth).should == 143466.84030197054
26
+ end
27
+ end
28
+ end
29
+
9
30
  describe '#now' do
10
31
  it 'returns current mars time' do
11
- earth = Time.utc(2012, 10, 15, 16, 50, 0)
12
- Time.should_receive(:now).and_return(earth)
32
+ earth = ::Time.utc(2012, 10, 15, 16, 50, 0)
33
+ ::Time.should_receive(:now).and_return(earth)
13
34
  DarianCalendar.now.should == DarianCalendar::Time.from_earth(earth)
14
35
  end
15
36
  end
37
+
38
+ describe '#today' do
39
+ it 'returns current mars date' do
40
+ earth = ::Date.new(2012, 10, 15)
41
+ ::Date.should_receive(:today).and_return(earth)
42
+ DarianCalendar.today.should == DarianCalendar::Date.from_earth(earth)
43
+ end
44
+ end
16
45
  end
17
46
 
18
47
  end
@@ -0,0 +1,202 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe DarianCalendar::Date do
6
+
7
+ before do
8
+ @earth_date = ::Date.new(2012, 10, 15)
9
+ @mars_date = DarianCalendar::Date.from_earth(@earth_date)
10
+ @mars_date_json = '{"calendar_type":"Martiana","month":14,"month_name":"Mithuna","month_of_season":1,"season":2,"sol":26,"sol_of_season":53,"sol_of_year":387,"total_sols":143466.15767923463,"week_sol":5,"week_sol_name":"Sol Jovis","year":214}'
11
+ end
12
+
13
+ describe 'attributes' do
14
+
15
+ it 'aliases day to sol and week day to week sol' do
16
+ @mars_date.day.should == @mars_date.sol
17
+ @mars_date.week_day.should == @mars_date.week_sol
18
+ end
19
+
20
+ end
21
+
22
+ describe 'initialize method' do
23
+ it 'converts earth date to mars date' do
24
+ @mars_date.year.should == 214
25
+ @mars_date.month.should == 14
26
+ @mars_date.sol.should == 26
27
+
28
+ @mars_date.total_sols.should == 143466.15767923463
29
+ @mars_date.season.should == 2
30
+ @mars_date.sol_of_season.should == 53
31
+ @mars_date.month_of_season.should == 1
32
+ @mars_date.sol_of_year.should == 387
33
+ @mars_date.week_sol.should == 5
34
+ end
35
+ end
36
+
37
+ describe 'class methods' do
38
+
39
+ describe '.from_earth' do
40
+ it 'converts an earth date to a mars date' do
41
+ DarianCalendar::Date.from_earth(@earth_date).should == @mars_date
42
+ end
43
+ end
44
+
45
+ describe '.parse_earth' do
46
+ it 'parses earth date and converts it to mars date' do
47
+ DarianCalendar::Date.parse_earth('2012-10-15').should == @mars_date
48
+ end
49
+ end
50
+
51
+ describe '.today' do
52
+ it 'returns current mars date' do
53
+ ::Date.should_receive(:today).and_return(@earth_date)
54
+ DarianCalendar::Date.today.should == DarianCalendar::Date.from_earth(@earth_date)
55
+ end
56
+ end
57
+
58
+ describe '.from_json' do
59
+ it 'parses a json string and creates a mars date' do
60
+ DarianCalendar::Date.from_json(@mars_date_json).should == @mars_date
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ describe 'instance methods' do
67
+
68
+ describe '#<=>' do
69
+ it 'compares mars date objects' do
70
+ same_date = DarianCalendar::Date.from_earth(Date.new(2012, 10, 15))
71
+ past_date = DarianCalendar::Date.from_earth(Date.new(2012, 10, 14))
72
+ future_date = DarianCalendar::Date.from_earth(Date.new(2012, 10, 16))
73
+
74
+ @mars_date.should == same_date
75
+ @mars_date.should > past_date
76
+ @mars_date.should < future_date
77
+
78
+ @mars_date.should_not < past_date
79
+ @mars_date.should_not > future_date
80
+ end
81
+ end
82
+
83
+ describe '#sols_in_year' do
84
+ it 'returns the number of sols in a martian year' do
85
+ leap_mars_date = DarianCalendar::Date.from_earth(Date.new(2013, 10, 15))
86
+ leap_mars_date.sols_in_year.should == 669
87
+ @mars_date.sols_in_year.should == 668
88
+ end
89
+ end
90
+
91
+ describe '#leap?' do
92
+ it 'returns if year is a leap year' do
93
+ leap_mars_date = DarianCalendar::Date.from_earth(Date.new(2013, 10, 15))
94
+ leap_mars_date.leap?.should == true
95
+ @mars_date.leap?.should == false
96
+ end
97
+ end
98
+
99
+ describe '#to_earth' do
100
+ it 'converts mars date to earth date' do
101
+ @earth_date == @mars_date.to_earth
102
+ end
103
+ end
104
+
105
+ describe '#to_s' do
106
+ it 'converts mars date to string' do
107
+ @mars_date.to_s.should == '214-14-26'
108
+ end
109
+ end
110
+
111
+ describe '#to_json' do
112
+ it 'converts mars date to a json string' do
113
+ @mars_date.to_json.should == @mars_date_json
114
+ end
115
+ end
116
+
117
+ describe '#as_json' do
118
+ it 'converts mars date to json' do
119
+ @mars_date.as_json.should == JSON::parse(@mars_date_json)
120
+ end
121
+ end
122
+
123
+ describe '#week_sol_name' do
124
+ context 'calendar type is not set' do
125
+ it 'returns "Sol Jovis"' do
126
+ @mars_date.week_sol_name.should == 'Sol Jovis'
127
+ end
128
+ end
129
+ context 'calendar type is "Martina"' do
130
+ it 'returns "Sol Jovis"' do
131
+ mars_date = DarianCalendar::Date.from_earth(@earth_date, DarianCalendar::CalendarTypes::MARTIANA)
132
+ mars_date.week_sol_name.should == 'Sol Jovis'
133
+ end
134
+ end
135
+ context 'calendar type is "Defrost"' do
136
+ it 'returns "Erjasol"' do
137
+ mars_date = DarianCalendar::Date.from_earth(@earth_date, DarianCalendar::CalendarTypes::DEFROST)
138
+ mars_date.week_sol_name.should == 'Erjasol'
139
+ end
140
+ end
141
+ context 'calendar type is "Areosynchronous"' do
142
+ it 'returns "Venusol"' do
143
+ mars_date = DarianCalendar::Date.from_earth(@earth_date, DarianCalendar::CalendarTypes::AREOSYNCHRONOUS)
144
+ mars_date.week_sol_name.should == 'Venusol'
145
+ end
146
+ end
147
+ context 'calendar type is "Hensel"' do
148
+ it 'returns "Sol Jovis"' do
149
+ mars_date = DarianCalendar::Date.from_earth(@earth_date, DarianCalendar::CalendarTypes::HENSEL)
150
+ mars_date.week_sol_name.should == 'Sol Jovis'
151
+ end
152
+ end
153
+ context 'calendar type is "Aqua"' do
154
+ it 'returns "5"' do
155
+ mars_date = DarianCalendar::Date.from_earth(@earth_date, DarianCalendar::CalendarTypes::AQUA)
156
+ mars_date.week_sol_name.should == '5'
157
+ end
158
+ end
159
+ end
160
+
161
+ describe '#month_name' do
162
+ context 'calendar type is not set' do
163
+ it 'returns "Mithuna"' do
164
+ @mars_date.month_name.should == 'Mithuna'
165
+ end
166
+ end
167
+ context 'calendar type is "Martina"' do
168
+ it 'returns "Mithuna"' do
169
+ mars_date = DarianCalendar::Date.from_earth(@earth_date, DarianCalendar::CalendarTypes::MARTIANA)
170
+ mars_date.month_name.should == 'Mithuna'
171
+ end
172
+ end
173
+ context 'calendar type is "Defrost"' do
174
+ it 'returns "Neturima"' do
175
+ mars_date = DarianCalendar::Date.from_earth(@earth_date, DarianCalendar::CalendarTypes::DEFROST)
176
+ mars_date.month_name.should == 'Neturima'
177
+ end
178
+ end
179
+ context 'calendar type is "Areosynchronous"' do
180
+ it 'returns "Neturima"' do
181
+ mars_date = DarianCalendar::Date.from_earth(@earth_date, DarianCalendar::CalendarTypes::AREOSYNCHRONOUS)
182
+ mars_date.month_name.should == 'Neturima'
183
+ end
184
+ end
185
+ context 'calendar type is "Hensel"' do
186
+ it 'returns "Duautumn"' do
187
+ mars_date = DarianCalendar::Date.from_earth(@earth_date, DarianCalendar::CalendarTypes::HENSEL)
188
+ mars_date.month_name.should == 'Duautumn'
189
+ end
190
+ end
191
+ context 'calendar type is "Aqua"' do
192
+ it 'returns "14"' do
193
+ mars_date = DarianCalendar::Date.from_earth(@earth_date, DarianCalendar::CalendarTypes::AQUA)
194
+ mars_date.month_name.should == '14'
195
+ end
196
+ end
197
+ end
198
+
199
+ end
200
+
201
+ end
202
+
@@ -2,4 +2,5 @@
2
2
 
3
3
  require 'time'
4
4
  require 'date'
5
+ require 'json'
5
6
  require Pathname(__FILE__).dirname.join('../lib/darian_calendar').to_s
@@ -5,8 +5,11 @@ require 'spec_helper'
5
5
  describe DarianCalendar::Time do
6
6
 
7
7
  before do
8
- @earth_time = Time.utc(2012, 10, 15, 16, 50, 0)
8
+ @earth_date = ::Date.new(2012, 10, 15)
9
+ @earth_time = ::Time.utc(2012, 10, 15, 16, 50, 0)
10
+ @mars_date = DarianCalendar::Date.from_earth(@earth_date)
9
11
  @mars_time = DarianCalendar::Time.from_earth(@earth_time)
12
+ @mars_time_json = '{"calendar_type":"Martiana","hour":20,"min":10,"month":14,"month_name":"Mithuna","month_of_season":1,"season":2,"sec":2,"sol":26,"sol_of_season":53,"sol_of_year":387,"total_sols":143466.84030197054,"week_sol":5,"week_sol_name":"Sol Jovis","year":214}'
10
13
  end
11
14
 
12
15
  describe 'attributes' do
@@ -38,10 +41,9 @@ describe DarianCalendar::Time do
38
41
 
39
42
  describe 'class methods' do
40
43
 
41
- describe '.total_sols' do
42
- it 'returns total sols from earth time' do
43
- sols = DarianCalendar::Time.sols_from_earth_time(@earth_time)
44
- sols.should == @mars_time.total_sols
44
+ describe '.from_earth' do
45
+ it 'converts an earth time to a mars time' do
46
+ DarianCalendar::Date.from_earth(@earth_time).should == @mars_time
45
47
  end
46
48
  end
47
49
 
@@ -51,13 +53,26 @@ describe DarianCalendar::Time do
51
53
  end
52
54
  end
53
55
 
56
+ describe '.today' do
57
+ it 'returns current mars date' do
58
+ ::Date.should_receive(:today).and_return(@earth_date)
59
+ DarianCalendar::Time.today.should == DarianCalendar::Date.from_earth(@earth_date)
60
+ end
61
+ end
62
+
54
63
  describe '.now' do
55
64
  it 'returns current mars time' do
56
- Time.should_receive(:now).and_return(@earth_time)
65
+ ::Time.should_receive(:now).and_return(@earth_time)
57
66
  DarianCalendar.now.should == DarianCalendar::Time.from_earth(@earth_time)
58
67
  end
59
68
  end
60
69
 
70
+ describe '.from_json' do
71
+ it 'parses a json string and creates a mars date' do
72
+ DarianCalendar::Time.from_json(@mars_time_json).should == @mars_time
73
+ end
74
+ end
75
+
61
76
  end
62
77
 
63
78
  describe 'instance methods' do
@@ -105,6 +120,24 @@ describe DarianCalendar::Time do
105
120
  end
106
121
  end
107
122
 
123
+ describe '#to_date' do
124
+ it 'returns the date of the mars time' do
125
+ @mars_time.to_date.should == @mars_date
126
+ end
127
+ end
128
+
129
+ describe '#to_json' do
130
+ it 'converts mars time to a json string' do
131
+ @mars_time.to_json.should == @mars_time_json
132
+ end
133
+ end
134
+
135
+ describe '#as_json' do
136
+ it 'converts mars time to json' do
137
+ @mars_time.as_json.should == JSON::parse(@mars_time_json)
138
+ end
139
+ end
140
+
108
141
  describe '#week_sol_name' do
109
142
  context 'calendar type is not set' do
110
143
  it 'returns "Sol Jovis"' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: darian_calendar
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.2'
4
+ version: '1.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Worreschk
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-08 00:00:00.000000000 Z
11
+ date: 2014-02-13 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: This Ruby library converts earth time to mars time and back again. You
14
14
  can choose between 5 variants of the Darian calendar system; Martiana, Defrost,
@@ -32,9 +32,11 @@ files:
32
32
  - Rakefile
33
33
  - darian_calendar.gemspec
34
34
  - lib/darian_calendar.rb
35
+ - lib/darian_calendar/date.rb
35
36
  - lib/darian_calendar/time.rb
36
37
  - lib/darian_calendar/version.rb
37
38
  - spec/darian_calendar_spec.rb
39
+ - spec/date_spec.rb
38
40
  - spec/spec_helper.rb
39
41
  - spec/time_spec.rb
40
42
  homepage: http://github.com/marsec/darian_calendar