prayer_times 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 88ba28e5dfcc4e57a3cb76df12221a046202ff41
4
+ data.tar.gz: d8d1255686349c190550f835fbd8d25e4f610344
5
+ SHA512:
6
+ metadata.gz: eed7fbbc8d954955ad284590a9e07f1784cbf41f1296185fc036fa331e1be13976d37d8110321d5af7e93a44fa7269b275689286c8c7a2ce7e7953912be33163
7
+ data.tar.gz: cf76f062cb054529ce1b40daab520bf555209ae643b712cb5ec4cf701c9d5b1d34c8e3be6a110e09ec5ff314619d2368d5e044381a893abc853a121cbdcbd311
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .project
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in prayer_times.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,14 @@
1
+ Copyright (c) 2013 Khaled alHabache
2
+
3
+ Original js Code: Hamid Zarrabi-Zadeh - PrayTimes.org
4
+
5
+ License: GNU LGPL v3.0
6
+
7
+ TERMS OF USE:
8
+ Permission is granted to use this code, with or
9
+ without modification, in any website or application
10
+ provided that credit is given to the original work
11
+ with a link back to PrayTimes.org.
12
+
13
+ This program is distributed in the hope that it will
14
+ be useful, but WITHOUT ANY WARRANTY.
data/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # PrayerTimes
2
+
3
+ Flexiable and configurable calculation for Muslim prayers times.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'prayer_times'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install prayer_times
18
+
19
+ ## Usage
20
+
21
+ ### Baisc usage
22
+
23
+ ```ruby
24
+ require 'prayer_times'
25
+ pt = PrayerTimes.new("Makkah")
26
+ times = pt.get_times(Date.today(), [31,36], 3)
27
+ puts times.inspect
28
+ ```
29
+
30
+ ### Global configuration
31
+
32
+ You can have a [global configuration](https://github.com/Startappz/prayer_times/wiki/Global-Configuration) through the PrayerTimes module:
33
+
34
+ ```ruby
35
+ require 'prayer_times'
36
+ PrayerTimes.time_format = '12h'
37
+ PrayerTimes.time_suffixes = {:am => 'صباحا', :pm => 'مساءا'}
38
+ # and others...
39
+ ```
40
+ #### Adding more methods
41
+
42
+ There are [several methods](https://github.com/Startappz/prayer_times/wiki/Calculation-Methods) that are shiped with this gem by default. You can list, add new or update existing ones.
43
+
44
+ ```ruby
45
+ PrayerTimes.calculation_methods
46
+ PrayerTimes.calculation_methods.names
47
+ PrayerTimes.calculation_methods.add("Test", "Testing method", fajr: 16.5, asr: 'Hanafi', isha: '80 min')
48
+ new_method = PrayerTimes.calculation_methods["Test"]
49
+ new_method.description = "new description"
50
+ new_method.settings = {fajr: 19.5, isha: '33 min'}
51
+ PrayerTimes.calculation_methods.delete("Test")
52
+ ```
53
+
54
+ ### Instance configuration
55
+
56
+ As with the global configuration, you can [set](https://github.com/Startappz/prayer_times/wiki/Instance-Configuration) the configuration on the object level:
57
+
58
+ ```ruby
59
+ require 'prayer_times'
60
+ PrayerTimes.time_format = '12h'
61
+ PrayerTimes.time_suffixes = {am: 'صباحا', pm: 'مساءا'}
62
+ options = {
63
+ time_format: '12h',
64
+ time_suffixes: {am: => 'صباحا', pm: 'مساءا'}
65
+ # and others...
66
+ }
67
+ pt = PrayerTimes.new("Makkah", options)
68
+ ```
69
+
70
+ ## Help
71
+
72
+ Youre help is appreciated, specially in adjusting the calculation methods and making them more accurate.
73
+ Your contribution is welcome.
74
+
75
+ ## Contributing
76
+
77
+ 1. Fork it
78
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
79
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
80
+ 4. Push to the branch (`git push origin my-new-feature`)
81
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'lib/prayer_times'
6
+ t.test_files = FileList['test/lib/prayer_times/*_test.rb']
7
+ t.verbose = true
8
+ end
9
+
10
+ task :default => :test
11
+
@@ -0,0 +1,236 @@
1
+ module PrayerTimes
2
+ # Calculation class used to do the times calculation in given settings
3
+ class Calculation
4
+ extend Forwardable
5
+ include MathHelpers
6
+
7
+ def_delegators :@calculator, :time_suffixes, :time_format, :invalid_time, :iterations_count, :times_offsets
8
+
9
+ # Gets the prayers times
10
+ # @param [PrayTime] calculator parent class
11
+ # @param [Date] date the desired date
12
+ # It accepts an array as well [year, month, day]
13
+ # @param [Array] coords of type [long, lat [,alt]]
14
+ # @param [Integer] time_zone the time zone
15
+ def initialize(calculator, date, coords, time_zone)
16
+ self.calculator = calculator
17
+ self.lat = coords[0]
18
+ self.lng = coords[1]
19
+ self.elv = coords.size > 2 ? coords[2] : 0
20
+ self.time_zone = time_zone
21
+ date = Date.new(date[0], date[1], date[2]) unless date.is_a? Date
22
+ self.jdate = date.ajd.to_f - lng / (15 * 24.0)
23
+ end
24
+
25
+ # Compute prayer times
26
+ # @return [Hash] times
27
+ def compute
28
+ times = {
29
+ imsak: 5, fajr: 5, sunrise: 6, dhuhr: 12,
30
+ asr: 13, sunset: 18, maghrib: 18, isha: 18
31
+ }
32
+ # main iterations
33
+ iterations_count.times{times = compute_prayer_times(times)}
34
+ times = adjust_times(times)
35
+
36
+ # add midnight time
37
+ if method_settings[:midnight] == 'Jafari'
38
+ times[:midnight] = times[:sunset] + time_diff(times[:sunset], times[:fajr]) / 2
39
+ else
40
+ times[:midnight] = times[:sunset] + time_diff(times[:sunset], times[:sunrise]) / 2
41
+ end
42
+
43
+ times = tune_times(times)
44
+ modify_formats(times)
45
+ set_names(times)
46
+ end
47
+
48
+ private
49
+
50
+ attr_accessor :calculator, :time_zone, :lat, :lng, :elv, :jdate
51
+
52
+
53
+ # convert float time to the given format (see time_formats)
54
+ def get_formatted_time(time)
55
+ return invalid_time if time.nan?
56
+ return time if time_format == 'Float'
57
+ time = fix_hour(time + 0.5 / 60) # add 0.5 minutes to round
58
+ hours = time.floor
59
+ minutes = ((time - hours) * 60).floor
60
+ suffix = time_format == '12h' ? time_suffixes[hours < 12 ? :am : :pm ] : ''
61
+ formatted_time = (time_format == "24h") ? ("%02d:%02d" % [hours, minutes]) : "%d:%02d" % [((hours + 11) % 12)+1, minutes]
62
+ formatted_time + suffix
63
+ end
64
+
65
+ # compute mid-day time
66
+ def mid_day(time)
67
+ eqt = sun_position(jdate + time)[1]
68
+ fix_hour(12 - eqt)
69
+ end
70
+
71
+ # compute the time at which sun reaches a specific angle below horizon
72
+ def sun_angle_time(angle, time, direction = nil)
73
+ decl = sun_position(jdate + time)[0]
74
+ noon = mid_day(time)
75
+ t = 1/15.0 * darccos((-rsin(angle)- rsin(decl)* rsin(lat))/
76
+ (rcos(decl) * rcos(lat)))
77
+ return noon + (direction == 'ccw' ? -t : t)
78
+ rescue
79
+ return (0/0.0)
80
+ end
81
+
82
+ # compute asr time
83
+ def asr_time(factor, time)
84
+ decl = sun_position(jdate + time)[0]
85
+ angle = -darccot(factor + rtan(lat - decl).abs)
86
+ sun_angle_time(angle, time)
87
+ end
88
+
89
+ # compute declination angle of sun and equation of time
90
+ # Ref: http://aa.usno.navy.mil/faq/docs/SunApprox.php
91
+ def sun_position(jd)
92
+ d = jd - 2451545.0
93
+ g = fix_angle(357.529 + 0.98560028 * d)
94
+ q = fix_angle(280.459 + 0.98564736 * d)
95
+ l = fix_angle(q + 1.915* rsin(g) + 0.020* rsin(2*g))
96
+
97
+ #r = 1.00014 - 0.01671 * cos(g) - 0.00014 * cos(2*g)
98
+ e = 23.439 - 0.00000036 * d
99
+
100
+ ra = darctan2(rcos(e)* rsin(l), rcos(l))/ 15.0
101
+ eqt = q / 15.0 - fix_hour(ra)
102
+ decl = darcsin(rsin(e)* rsin(l))
103
+
104
+ [decl, eqt]
105
+ end
106
+
107
+
108
+ # compute prayer times at given julian date
109
+ def compute_prayer_times(times)
110
+ day_portion(times)
111
+ {
112
+ imsak: sun_angle_time(method_settings[:imsak].to_f, times[:imsak], 'ccw'),
113
+ fajr: sun_angle_time(method_settings[:fajr].to_f, times[:fajr], 'ccw'),
114
+ sunrise: sun_angle_time(rise_set_angle(elv), times[:sunrise], 'ccw'),
115
+ dhuhr: mid_day(times[:dhuhr]),
116
+ asr: asr_time(asr_factor(method_settings[:asr]), times[:asr]),
117
+ sunset: sun_angle_time(rise_set_angle(elv), times[:sunset]),
118
+ maghrib: sun_angle_time(method_settings[:maghrib].to_f, times[:maghrib]),
119
+ isha: sun_angle_time(method_settings[:isha].to_f, times[:isha])
120
+ }
121
+ end
122
+
123
+ # adjust times in a prayer time array
124
+ def adjust_times(times)
125
+ tz_adjust = time_zone - lng / 15.0
126
+ times.keys.each{|k| times[k] += tz_adjust}
127
+ if !method_settings[:high_lats].nil?
128
+ times = adjust_high_lats(times)
129
+ end
130
+
131
+ if minute?(method_settings[:imsak])
132
+ times[:imsak] = times[:fajr] - method_settings[:imsak].to_f / 60.0
133
+ end
134
+ # need to ask about 'min' settings
135
+ if minute?(method_settings[:maghrib])
136
+ times[:maghrib] = times[:sunset] + method_settings[:maghrib].to_f / 60.0
137
+ end
138
+ if minute?(method_settings[:isha])
139
+ times[:isha] = times[:maghrib] + method_settings[:isha].to_f / 60.0
140
+ end
141
+
142
+ times[:dhuhr] += method_settings[:dhuhr].to_f / 60.0
143
+
144
+ return times
145
+ end
146
+
147
+ # get asr shadow factor
148
+ def asr_factor(asr)
149
+ calc_methods = {'Standard' => 1, 'Hanafi' => 2}
150
+ calc_methods.include?(asr) ? calc_methods[asr] : asr.to_f
151
+ end
152
+
153
+ # return sun angle for sunset/sunrise
154
+ def rise_set_angle(elevation = 0)
155
+ 0.833 + 0.0347 * Math.sqrt(elevation) # an approximation
156
+ end
157
+
158
+ # apply offsets to the times
159
+ def tune_times(times)
160
+ times.each{|k,_| times[k] += (method_offsets[k] + times_offsets[k]) / 60.0}
161
+ end
162
+
163
+ # convert times to given time format
164
+ def modify_formats(times)
165
+ times.each{|k,_| times[k] = get_formatted_time(times[k])}
166
+ end
167
+
168
+ def set_names(times)
169
+ res = {}
170
+ calculator.times_names.each{|k,v| res[v] = times[k]}
171
+ res
172
+ end
173
+
174
+ # adjust times for locations in higher latitudes
175
+ def adjust_high_lats(times)
176
+ night_time = time_diff(times[:sunset], times[:sunrise]) # sunset to sunrise
177
+ times[:imsak] = adjust_hl_time(times[:imsak], times[:sunrise], method_settings[:imsak].to_f, night_time, 'ccw')
178
+ times[:fajr] = adjust_hl_time(times[:fajr], times[:sunrise], method_settings[:fajr].to_f, night_time, 'ccw')
179
+ times[:isha] = adjust_hl_time(times[:isha], times[:sunset], method_settings[:isha].to_f, night_time)
180
+ times[:maghrib] = adjust_hl_time(times[:maghrib], times[:sunset], method_settings[:maghrib].to_f, night_time)
181
+ times
182
+ end
183
+
184
+ # adjust a time for higher latitudes
185
+ def adjust_hl_time(time, base, angle, night, direction = nil)
186
+ portion = night_portion(angle, night)
187
+ diff = direction == 'ccw' ? time_diff(time, base) : time_diff(base, time)
188
+ if time.nan? or (diff > portion)
189
+ time = base + (direction == 'ccw' ? - portion : portion)
190
+ end
191
+ time
192
+ end
193
+
194
+ # the night portion used for adjusting times in higher latitudes
195
+ def night_portion(angle, night)
196
+ hl_method = method_settings[:high_lats]
197
+ portion = 1/2.0 # midnight
198
+ portion = 1/60.0 * angle if hl_method == 'AngleBased'
199
+ portion = 1/7.0 if hl_method == 'OneSeventh'
200
+ portion * night
201
+ end
202
+
203
+ # convert hours to day portions
204
+ def day_portion(times)
205
+ times.each{|k,v| times[k] = times[k] / 24.0}
206
+ end
207
+
208
+ # compute the difference between two times
209
+ def time_diff(time1, time2); fix_hour(time2 - time1); end
210
+
211
+
212
+ # detect if input contains 'min'
213
+ def minute?(arg); arg.to_s.include? "min"; end
214
+
215
+ def fix_hour(hour); fix(hour, 24.0) ; end
216
+
217
+
218
+ def fix_angle(angle); fix(angle, 360.0) ; end
219
+
220
+ def fix(a, mode)
221
+ return a if a.nan?
222
+ a = a - mode * (a / mode).floor
223
+ a < 0 ? a + mode : a
224
+ end
225
+
226
+ def method_settings
227
+ @m_settings ||= calculator.calculation_method.settings
228
+ end
229
+
230
+ def method_offsets
231
+ @m_offsets ||= calculator.calculation_method.offsets
232
+ end
233
+
234
+ end
235
+
236
+ end
@@ -0,0 +1,85 @@
1
+ module PrayerTimes
2
+ # Calculation method instances and logic is encapsulated here
3
+ class CalculationMethod
4
+ attr_reader :name, :description, :settings, :offsets
5
+ attr_writer :description
6
+
7
+ # Default settings
8
+ def self.default_settings
9
+ {
10
+ imsak: '10 min',
11
+ dhuhr: '0 min',
12
+ asr: 'Standard',
13
+ maghrib: '0 min',
14
+ midnight: 'Standard',
15
+ high_lats: 'NightMiddle'
16
+ }
17
+ end
18
+
19
+ # Initializer
20
+ # @param [String] name
21
+ # @param [String] description
22
+ # @param [Hash] settings
23
+ # @option settings [String] :imsak
24
+ # @option settings [String] :fajr
25
+ # @option settings [String] :sunrise
26
+ # @option settings [String] :dhuhr
27
+ # @option settings [String] :asr Asr Juristic Methods:
28
+ # 'Standard': Shafi`i, Maliki, Ja`fari and Hanbali,
29
+ # 'Hanafi': Hanafi
30
+ # @option settings [String] :sunset
31
+ # @option settings [String] :maghrib
32
+ # @option settings [String] :isha
33
+ # @option settings [String] :midnight Midnight Mode:
34
+ # 'Standard': Mid Sunset to Sunrise,
35
+ # 'Jafari': Mid Sunset to Fajr
36
+ # @option settings [String] :high_lights Adjust Methods for Higher Latitudes:
37
+ # 'NightMiddle': middle of night,
38
+ # 'AngleBased': angle/60th of night,
39
+ # 'OneSeventh': 1/7th of night,
40
+ # 'None'
41
+ # @param [Hash] offsets
42
+ # @option offsets [String] :imsak
43
+ # @option offsets [String] :fajr
44
+ # @option offsets [String] :sunrise
45
+ # @option offsets [String] :dhuhr
46
+ # @option offsets [String] :asr
47
+ # @option offsets [String] :sunset
48
+ # @option offsets [String] :maghrib
49
+ # @option offsets [String] :isha
50
+ # @option offsets [String] :midnight
51
+ def initialize(name,description,settings={}, offsets = {})
52
+ self.name = name
53
+ self.description = description
54
+ self.settings = settings
55
+ self.offsets = offsets
56
+ end
57
+
58
+ # Sets times settings
59
+ # @param [Hash] settings
60
+ # Check the initializer
61
+ def settings=(settings)
62
+ s = settings.reject{|k,v| !(Constants.times_names.key?(k))} rescue {}
63
+ @settings = self.class.default_settings.merge(s)
64
+ end
65
+
66
+ # Sets times offsets
67
+ # @param [Hash] offsets
68
+ # Check the initializer
69
+ def offsets=(offsets)
70
+ s = offsets.reject{|k,v| !(Constants.times_offsets.key?(k) and v.is_a?(Numeric))} rescue {}
71
+ @offsets = Constants.times_offsets.merge(s)
72
+ end
73
+
74
+
75
+ # @return readable representation of this object
76
+ def to_s
77
+ name
78
+ end
79
+
80
+ private
81
+
82
+ attr_writer :name
83
+
84
+ end
85
+ end
@@ -0,0 +1,144 @@
1
+ module PrayerTimes
2
+ # Helper class to initiate a list of calculation methods and add/update others
3
+ class CalculationMethods
4
+ extend Forwardable
5
+ def_delegators :@hash, :[], :length, :each, :key?, :keys, :delete, :to_s
6
+
7
+ # default methods defined in this gem
8
+ # Methods MWL, ISNA, Egypt, Makkah, Karachi, Tehran and Jafari are accurate
9
+ # Other methods need validation. Your help is appreciated.
10
+ def self.default_methods
11
+ {
12
+ "MWL" =>{
13
+ desc: 'Muslim World League',
14
+ settings: {fajr: 18, isha: 17}
15
+ },
16
+ 'ISNA' => {
17
+ desc: 'Islamic Society of North America (ISNA)',
18
+ settings: {fajr: 15, isha: 15}
19
+ },
20
+ 'Egypt' => {
21
+ desc: 'Egyptian General Authority of Survey',
22
+ settings: {fajr: 19.5, isha: 17.5}
23
+ },
24
+ 'Makkah' => {
25
+ desc: 'Umm Al-Qura University, Makkah',
26
+ settings: {fajr: 18.5, isha: '90 min'} # fajr was 19 degrees before 1430 hijri
27
+ },
28
+ 'Karachi' => {
29
+ desc: 'University of Islamic Sciences, Karachi',
30
+ settings: {fajr: 18, isha: 18}
31
+ },
32
+ 'Tehran' => {
33
+ desc: 'Institute of Geophysics, University of Tehran',
34
+ settings: {fajr: 17.7, maghrib: 4.5, isha: 14, midnight: 'Jafari'} # isha is not explicitly specified in this method
35
+ },
36
+ 'Jafari' => {
37
+ desc: 'Shia Ithna-Ashari, Leva Institute, Qum',
38
+ settings: {fajr: 16, maghrib: 4, isha: 14, midnight: 'Jafari'}
39
+ },
40
+ 'UOIF' =>{
41
+ desc: "UNION DES ORGANISATIONS ISLAMIQUES DE FRANCE",
42
+ settings: {fajr: 19, maghrib: '0 min', isha: 17}
43
+ },
44
+ 'Algeria' =>{
45
+ desc: "Algeria",
46
+ settings: {fajr: 18, maghrib: '3 min', isha: 17}
47
+ },
48
+ 'EmirateDubai' =>{
49
+ desc: "Emirate, Dubai",
50
+ settings: {fajr: 18.5, maghrib: '0 min', isha: '90 min'},
51
+ offsets: {dhuhr: 4, asr: 5, maghrib: 2}
52
+ },
53
+ 'Emirates' =>{
54
+ desc: "Emirates",
55
+ settings: {fajr: 18.5, maghrib: '0 min', isha: '90 min'},
56
+ offsets: {asr: 4, maghrib: 2}
57
+ },
58
+ 'EnglandBirmingham' =>{
59
+ desc: "England, Birmingham",
60
+ settings: {fajr: 5, maghrib: '0 min', isha: 84},
61
+ offsets: {fajr: -60, isha: 60}
62
+ },
63
+ 'Jordan' =>{
64
+ desc: "General Iftaa' Department, The Hashemite Kingdom of Jordan",
65
+ settings: {fajr: 18, maghrib: '0 min', isha: 18}
66
+ },
67
+ 'Kuwait' =>{
68
+ desc: "Kuwait",
69
+ settings: {fajr: 18, maghrib: '0 min', isha: 17.5}
70
+ },
71
+ 'Libya' =>{
72
+ desc: "Libya",
73
+ settings: {fajr: 18.5, maghrib: '0 min', isha: 18.5},
74
+ offsets: { dhuhr: 4, maghrib: 4}
75
+ },
76
+ 'Malaysia' =>{
77
+ desc: "Malaysia",
78
+ settings: {fajr: 20, maghrib: '0 min', isha: 18},
79
+ offsets: {fajr: 3, sunrise: 2, dhuhr: 1, asr: 2, maghrib: 1, isha: -1}
80
+ },
81
+ 'Maldives' =>{
82
+ desc: "Maldives",
83
+ settings: {fajr: 19, maghrib: '0 min', isha: 19},
84
+ offsets: {sunrise: -1, dhuhr: 4, asr: 1, maghrib: 1, isha: 1}
85
+ },
86
+ 'Morocco' =>{
87
+ desc: "Morocco",
88
+ settings: {fajr: 19, maghrib: '0 min', isha: 17},
89
+ offsets: {fajr: -1, sunrise: -2, dhuhr: 5, maghrib: 3}
90
+ },
91
+ 'Oman' =>{
92
+ desc: "Oman",
93
+ settings: {fajr: 18, maghrib: '5 min', isha: 18},
94
+ offsets: {dhuhr: 5, asr: 5, isha: 1}
95
+ },
96
+ 'Qatar' =>{
97
+ desc: "Qatar",
98
+ settings: {fajr: 18, maghrib: '0 min', isha: '90 min'}
99
+ },
100
+ 'Tunisia' =>{
101
+ desc: "Tunisia",
102
+ settings: {fajr: 18, maghrib: '1 min', isha: 18},
103
+ offsets: {fajr: -1, sunrise: -2, dhuhr: 8, isha: 1}
104
+ },
105
+ 'Turkey' =>{
106
+ desc: "Presidency of Religious Affairs, Turkey",
107
+ settings: {fajr: 18, maghrib: '9 min', isha: 17},
108
+ offsets: {fajr: -2, sunrise: -7, dhuhr: 6, asr: 4, isha: 2}
109
+ }
110
+ }
111
+ end
112
+
113
+ # Initializer
114
+ # it populates a hash with predefined set of methods
115
+ def initialize
116
+ self.hash = {}
117
+ populate
118
+ end
119
+
120
+ # @param [String] name
121
+ # @param [String] description
122
+ # @param [Hash] settings
123
+ # @param [Hash] offsets
124
+ # @see CalculationMethod
125
+ def add(name, description, settings={}, offsets={})
126
+ hash[name] = CalculationMethod.new(name, description, settings, offsets)
127
+ end
128
+
129
+ # Names of the available methods
130
+ # @return [Array] list of names
131
+ def names
132
+ keys
133
+ end
134
+
135
+ private
136
+
137
+ attr_accessor :hash
138
+
139
+ def populate
140
+ self.class.default_methods.each {|k,v| add(k, v[:desc], v[:settings], v[:offsets])}
141
+ end
142
+
143
+ end
144
+ end
@@ -0,0 +1,57 @@
1
+ module PrayerTimes
2
+ # This is main interface class
3
+ class Calculator
4
+ include Setters
5
+
6
+ attr_reader :calculation_method, :time_format, :times_names, :time_suffixes, :invalid_time, :iterations_count, :times_offsets
7
+
8
+ # Initializer
9
+ # @param [String] calc_method the calculation method to use
10
+ # @param [Hash] opts formatting options
11
+ # @option opts [String] :time_format
12
+ # @option opts [String] :invalid_time
13
+ # @option opts [String] :time_suffixes
14
+ # @option opts [String] :times_names
15
+ # @option opts [String] :times_offsets
16
+ # @option opts [String] :iterations_count this is algorithmic option. Don't set it unless you know what you are doing
17
+ # @see Setters to get an idea about those options
18
+ def initialize(calc_method, opts)
19
+ self.calculation_method = calc_method
20
+
21
+ self.time_format = opts[:time_format]
22
+
23
+ self.invalid_time = opts[:invalid_time]
24
+
25
+ self.time_suffixes = (opts[:time_suffixes])
26
+
27
+ self.times_names = (opts[:times_names])
28
+
29
+ self.times_offsets = (opts[:times_offsets])
30
+
31
+ self.iterations_count = opts[:iterations_count]
32
+ end
33
+
34
+
35
+
36
+ # Gets the prayers times
37
+ # @param [Date] date the date
38
+ # @param [Array] coords of type [long, lat [,alt]]
39
+ # @param [Integer] time_zone the time zone
40
+ # @param [Integer] dst Daylight saving time
41
+ # @return [Hash] times
42
+ def get_times(date, coords, time_zone, dst = nil)
43
+ Calculation.new(self,
44
+ date,
45
+ coords,
46
+ time_zone + (dst.nil? ? 0 : 1)).
47
+ compute
48
+ end
49
+
50
+ private
51
+
52
+ def const_class
53
+ PrayerTimes
54
+ end
55
+
56
+ end
57
+ end