darian_calendar 0.2 → 1.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 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