prayer_times 0.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 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