class Prayertimes::Calculate
Public Class Methods
# File lib/prayertimes.rb, line 97 def initialize(method = "MWL") @@methods.each do |method, config| @@defaultParams.each do |name, value| # if name in config['params'] || config['params'][name] != nil config['params'][name] = value # end end end @@calcMethod = method #if method in @@methods else 'MWL' params = @@methods[@@calcMethod]['params'] params.each do |name, value| @@settings[name] = value end @@timeNames.each do |name, value| @@offset[name] = 0 end end
Public Instance Methods
# File lib/prayertimes.rb, line 129 def adjust(params) @@settings.update(params) end
adjust a time for higher latitudes
# File lib/prayertimes.rb, line 369 def adjustHLTime(time, base, angle, night, direction = nil) portion = self.nightPortion(angle, night) diff = direction == 'ccw' ? self.timeDiff(time, base) : self.timeDiff(base, time) if time.nan? or diff > portion time = base + ( direction == 'ccw' ? -portion : portion) end return time end
adjust times for locations in higher latitudes
# File lib/prayertimes.rb, line 358 def adjustHighLats(times) params = @@settings nightTime = self.timeDiff(times['sunset'], times['sunrise']) # sunset to sunrise times['imsak'] = self.adjustHLTime(times['imsak'], times['sunrise'], self.eval(params['imsak']), nightTime, 'ccw') times['fajr'] = self.adjustHLTime(times['fajr'], times['sunrise'], self.eval(params['fajr']), nightTime, 'ccw') times['isha'] = self.adjustHLTime(times['isha'], times['sunset'], self.eval(params['isha']), nightTime) times['maghrib'] = self.adjustHLTime(times['maghrib'], times['sunset'], self.eval(params['maghrib']), nightTime) return times end
adjust times in a prayer time array
# File lib/prayertimes.rb, line 301 def adjustTimes(times) params = @@settings tzAdjust = @timeZone - @lng / 15.0 times.each do |t,v| times[t] += tzAdjust end if params['highLats'] != nil times = self.adjustHighLats(times) end if self.isMin(params['imsak']) times['imsak'] = times['fajr'] - self.eval(params['imsak']) / 60.0 end # need to ask about '@@settings if self.isMin(params['maghrib']) times['maghrib'] = times['sunset'] - self.eval(params['maghrib']) / 60.0 end if self.isMin(params['isha']) times['isha'] = times['maghrib'] - self.eval(params['isha']) / 60.0 end times['dhuhr'] += self.eval(params['dhuhr']) / 60.0 return times end
# File lib/prayertimes.rb, line 426 def arccos(x) return ((Math.acos(x)* 180.0) / Math::PI); end
# File lib/prayertimes.rb, line 429 def arccot(x) return ((Math.atan(1.0/x)* 180.0) / Math::PI); end
# File lib/prayertimes.rb, line 425 def arcsin(x) return ((Math.asin(x)* 180.0) / Math::PI); end
# File lib/prayertimes.rb, line 427 def arctan(x) return ((Math.atan(x)* 180.0) / Math::PI); end
# File lib/prayertimes.rb, line 430 def arctan2(y, x) return ((Math.atan2(y, x)* 180.0) / Math::PI); end
get asr shadow factor
# File lib/prayertimes.rb, line 329 def asrFactor(asrParam) methods = {'Standard'=> 1, 'Hanafi'=> 2} return methods[asrParam] ? methods[asrParam] : self.eval(asrParam) end
compute asr time
# File lib/prayertimes.rb, line 221 def asrTime(factor, time) decl = self.sunPosition(@jDate + time)[0] angle = -self.arccot(factor + self.tan((@lat - decl).abs)) return self.sunAngleTime(angle, time) end
compute prayer times at given julian date
# File lib/prayertimes.rb, line 260 def computePrayerTimes(times) times = self.dayPortion(times) params = @@settings imsak = self.sunAngleTime(self.eval(params['imsak']), times['imsak'], 'ccw') fajr = self.sunAngleTime(self.eval(params['fajr']), times['fajr'], 'ccw') sunrise = self.sunAngleTime(self.riseSetAngle(@elv), times['sunrise'], 'ccw') dhuhr = self.midDay(times['dhuhr']) asr = self.asrTime(self.asrFactor(params['asr']), times['asr']) sunset = self.sunAngleTime(self.riseSetAngle(@elv), times['sunset']) maghrib = self.sunAngleTime(self.eval(params['maghrib']), times['maghrib']) isha = self.sunAngleTime(self.eval(params['isha']), times['isha']) return { 'imsak'=> imsak, 'fajr'=> fajr, 'sunrise'=> sunrise, 'dhuhr'=> dhuhr, 'asr'=> asr, 'sunset'=> sunset, 'maghrib'=> maghrib, 'isha'=> isha } end
compute prayer times
# File lib/prayertimes.rb, line 279 def computeTimes times = { 'imsak'=> 5, 'fajr'=> 5, 'sunrise'=> 6, 'dhuhr'=> 12, 'asr'=> 13, 'sunset'=> 18, 'maghrib'=> 18, 'isha'=> 18 } # main iterations @@numIterations.times do times = self.computePrayerTimes(times) end times = self.adjustTimes(times) # add midnight time if @@settings['midnight'] == 'Jafari' times['midnight'] = times['sunset'] + self.timeDiff(times['sunset'], times['fajr']) / 2 else times['midnight'] = times['sunset'] + self.timeDiff(times['sunset'], times['sunrise']) / 2 end times = self.tuneTimes(times) return self.modifyFormats(times) end
# File lib/prayertimes.rb, line 422 def cos(d) return Math.cos((d) * Math::PI / 180); end
convert hours to day portions
# File lib/prayertimes.rb, line 392 def dayPortion(times) times.each do |key, value| times[key] = value /= 24.0 end return times end
convert given string into a number
# File lib/prayertimes.rb, line 408 def eval(st) val = st.to_s.split('[^0-9.+-]')[0] return val ? val.to_f : 0 end
# File lib/prayertimes.rb, line 435 def fix(a, mode) if a.nan? return a end a = a - mode * ((a / mode).floor) return a < 0 ? a + mode : a end
# File lib/prayertimes.rb, line 432 def fixangle(angle) return self.fix(angle, 360.0); end
# File lib/prayertimes.rb, line 433 def fixhour(hour) return self.fix(hour, 24.0); end
# File lib/prayertimes.rb, line 149 def getDefaults return @@methods end
convert float time to the given format (see timeFormats)
# File lib/prayertimes.rb, line 174 def getFormattedTime(time, format, suffixes = nil) return self.invalidTime if time.nan? return time if format == 'Float' suffixes = @@timeSuffixes if suffixes == nil time = self.fixhour(time+ 0.5/ 60) # add 0.5 minutes to round hours = time.floor minutes = ((time - hours)* 60).floor suffix = format == '12h' ? suffixes[ hours < 12 ? 0 : 1 ] : '' if format == "24h" formattedTime = "#{hours}:#{minutes}" else formattedTime = "#{(hours+11)%12+1}:#{minutes}" end return formattedTime + suffix end
# File lib/prayertimes.rb, line 137 def getMethod return @@calcMethod end
# File lib/prayertimes.rb, line 145 def getOffsets return @@offset end
# File lib/prayertimes.rb, line 141 def getSettings return @@settings end
return prayer times for a given date
# File lib/prayertimes.rb, line 154 def getTimes(date, coords, timezone, dst = 0, format = nil) @lat = coords[0] @lng = coords[1] @elv = coords.length >2 ? coords[2] : 0 if format != nil @@timeFormat = format end if Date.parse(date) date = Date.parse(date) date = [date.year, date.month, date.day] end @timeZone = timezone + (dst ? 1 : 0) @jDate = self.julian(date[0], date[1], date[2]) - @lng / (15 * 24.0) return self.computeTimes end
detect if input contains 'min'
# File lib/prayertimes.rb, line 414 def isMin(arg) return arg.to_s.include?('min') end
convert Gregorian date to Julian day Ref: Astronomical Algorithms by Jean Meeus
# File lib/prayertimes.rb, line 247 def julian(year, month, day) if month <= 2 year -= 1 month += 12 end a = (year / 100).floor b = 2 - a + (a / 4).floor return (365.25 * (year + 4716)).floor + (30.6001 * (month + 1)).floor + day + b - 1524.5 end
compute mid-day time
# File lib/prayertimes.rb, line 200 def midDay(time) eqt = self.sunPosition(@jDate + time)[1] return self.fixhour(12 - eqt) end
convert times to given time format
# File lib/prayertimes.rb, line 350 def modifyFormats(times) times.each do |name, value| times[name] = self.getFormattedTime(times[name], @@timeFormat) end return times end
the night portion used for adjusting times in higher latitudes
# File lib/prayertimes.rb, line 379 def nightPortion(angle, night) method = @@settings['highLats'] portion = 1/2.0 # midnight if method == 'AngleBased' portion = 1/60.0 * angle end if method == 'OneSeventh' portion = 1/7.0 end return portion * night end
return sun angle for sunset/sunrise
# File lib/prayertimes.rb, line 335 def riseSetAngle(elevation = 0) elevation = elevation == nil ? 0 : elevation return 0.833 + 0.0347 * Math.sqrt(elevation) # an approximation end
# File lib/prayertimes.rb, line 122 def setMethod(method) if @@methods[method] self.adjust(@@methods[method]["params"]) @@calcMethod = method end end
# File lib/prayertimes.rb, line 421 def sin(d) return Math.sin((d) * Math::PI / 180); end
compute the time at which sun reaches a specific angle below horizon
# File lib/prayertimes.rb, line 206 def sunAngleTime(angle, time, direction = nil) angle time begin decl = self.sunPosition(@jDate + time)[0] noon = self.midDay(time) t = 1/15.0* self.arccos((-self.sin(angle)- self.sin(decl)* self.sin(@lat))/ (self.cos(decl)* self.cos(@lat))) return noon + (direction == 'ccw' ? -t : t) rescue return ('nan').to_f end end
compute declination angle of sun and equation of time Ref: aa.usno.navy.mil/faq/docs/SunApprox.php
# File lib/prayertimes.rb, line 229 def sunPosition(jd) d = jd - 2451545.0 g = self.fixangle(357.529 + 0.98560028* d) q = self.fixangle(280.459 + 0.98564736* d) l = self.fixangle(q + 1.915* self.sin(g) + 0.020* self.sin(2*g)) r = 1.00014 - 0.01671*self.cos(g) - 0.00014*self.cos(2*g) e = 23.439 - 0.00000036* d ra = self.arctan2(self.cos(e)* self.sin(l), self.cos(l))/ 15.0 eqt = q/15.0 - self.fixhour(ra) decl = self.arcsin(self.sin(e)* self.sin(l)) return [decl, eqt] end
# File lib/prayertimes.rb, line 423 def tan(d) return Math.tan((d) * Math::PI / 180); end
compute the difference between two times
# File lib/prayertimes.rb, line 403 def timeDiff(time1, time2) return self.fixhour(time2- time1) end
# File lib/prayertimes.rb, line 133 def tune(timeOffsets) @@offset.update(timeOffsets) end
apply offset to the times
# File lib/prayertimes.rb, line 341 def tuneTimes(times) times.each do |name, value| @@offset times[name] += @@offset[name] / 60.0 end return times end