UNPKG

praytime

Version:

A JavaScript library for calculating prayer times.

1 lines 5.09 kB
class PrayTime{constructor(t){this.methods={MWL:{fajr:18,isha:17},ISNA:{fajr:15,isha:15},Egypt:{fajr:19.5,isha:17.5},Makkah:{fajr:18.5,isha:"90 min"},Karachi:{fajr:18,isha:18},Tehran:{fajr:17.7,maghrib:4.5,midnight:"Jafari"},Jafari:{fajr:16,maghrib:4,midnight:"Jafari"},defaults:{isha:14,maghrib:"1 min",midnight:"Standard"}},this.settings={dhuhr:"0 min",asr:"Standard",highLats:"NightMiddle",tune:{},format:"24h",rounding:"nearest",utcOffset:"auto",location:[0,-(new Date).getTimezoneOffset()/4],iterations:1},this.labels=["Fajr","Sunrise","Dhuhr","Asr","Sunset","Maghrib","Isha","Midnight"],this.method(t||"MWL")}method(t){return this.set(this.methods.defaults).set(this.methods[t])}adjust(t){return this.set(t)}location(t){return this.set({location:t})}tune(t){return this.set({tune:t})}round(t="nearest"){return this.set({rounding:t})}format(t){return this.set({format:t})}set(t){return Object.assign(this.settings,t),this}utcOffset(t="auto"){return"number"==typeof t&&Math.abs(t)<16&&(t*=60),this.set({utcOffset:t})}times(t=0){"number"==typeof t&&(t=new Date(t<1e3?Date.now()+864e5*t:t)),t.constructor===Date&&(t=[t.getFullYear(),t.getMonth()+1,t.getDate()]),this.utcTime=Date.UTC(t[0],t[1]-1,t[2]);let s=this.computeTimes();return this.formatTimes(s),s}getTimes(t,s,i="auto",e=0,a="24h"){const n="auto"==i?i:i+e;return this.location(s).utcOffset(n).format(a),this.times(t)}setMethod(t){this.method(t)}computeTimes(){let t={fajr:5,sunrise:6,dhuhr:12,asr:13,sunset:18,maghrib:18,isha:18,midnight:24};for(let s=0;s<this.settings.iterations;s++)t=this.processTimes(t);return this.adjustHighLats(t),this.updateTimes(t),this.tuneTimes(t),this.convertTimes(t),t}processTimes(t){const s=this.settings;return{fajr:this.angleTime(s.fajr,t.fajr,-1),sunrise:this.angleTime(.833,t.sunrise,-1),dhuhr:this.midDay(t.dhuhr),asr:this.angleTime(this.asrAngle(s.asr,t.asr),t.asr),sunset:this.angleTime(.833,t.sunset),maghrib:this.angleTime(s.maghrib,t.maghrib),isha:this.angleTime(s.isha,t.isha),midnight:this.midDay(t.midnight)+12}}updateTimes(t){const s=this.settings;if(this.isMin(s.maghrib)&&(t.maghrib=t.sunset+this.value(s.maghrib)/60),this.isMin(s.isha)&&(t.isha=t.maghrib+this.value(s.isha)/60),"Jafari"==s.midnight){const i=this.angleTime(s.fajr,29,-1)+24;t.midnight=(t.sunset+(this.adjusted?t.fajr+24:i))/2}t.dhuhr+=this.value(s.dhuhr)/60}tuneTimes(t){const s=this.settings.tune;for(let i in t)i in s&&(t[i]+=s[i]/60)}convertTimes(t){const s=this.settings.location[1];for(let i in t){const e=t[i]-s/15,a=this.utcTime+Math.floor(36e5*e);t[i]=this.roundTime(a)}}roundTime(t){const s={up:"ceil",down:"floor",nearest:"round"}[this.settings.rounding];if(!s)return t;return 6e4*Math[s](t/6e4)}sunPosition(t){const s=this.settings.location[1],i=this.utcTime/864e5-10957.5+this.value(t)/24-s/360,e=this.mod(357.529+.98560028*i,360),a=this.mod(280.459+.98564736*i,360),n=this.mod(a+1.915*this.sin(e)+.02*this.sin(2*e),360),h=23.439-36e-8*i,r=this.mod(this.arctan2(this.cos(h)*this.sin(n),this.cos(n))/15,24);return{declination:this.arcsin(this.sin(h)*this.sin(n)),equation:a/15-r}}midDay(t){const s=this.sunPosition(t).equation;return this.mod(12-s,24)}angleTime(t,s,i=1){const e=this.settings.location[0],a=this.sunPosition(s).declination,n=-this.sin(t)-this.sin(e)*this.sin(a),h=this.arccos(n/(this.cos(e)*this.cos(a)))/15;return this.midDay(s)+h*i}asrAngle(t,s){const i={Standard:1,Hanafi:2}[t]||this.value(t),e=this.settings.location[0],a=this.sunPosition(s).declination;return-this.arccot(i+this.tan(Math.abs(e-a)))}adjustHighLats(t){const s=this.settings;if("None"==s.highLats)return;this.adjusted=!1;const i=24+t.sunrise-t.sunset;Object.assign(t,{fajr:this.adjustTime(t.fajr,t.sunrise,s.fajr,i,-1),isha:this.adjustTime(t.isha,t.sunset,s.isha,i),maghrib:this.adjustTime(t.maghrib,t.sunset,s.maghrib,i)})}adjustTime(t,s,i,e,a=1){const n={NightMiddle:.5,OneSeventh:1/7,AngleBased:1/60*this.value(i)}[this.settings.highLats]*e,h=(t-s)*a;return(isNaN(t)||h>n)&&(t=s+n*a,this.adjusted=!0),t}formatTimes(t){for(let s in t)t[s]=this.formatTime(t[s])}formatTime(t){const s=this.settings.format;return isNaN(t)?"-----":"function"==typeof s?s(t):"x"==s.toLowerCase()?Math.floor(t/("X"==s?1e3:1)):this.timeToString(t,s)}timeToString(t,s){const i=new Date(t),e=this.settings.utcOffset,a="auto"==e?-i.getTimezoneOffset():e,n=60*i.getUTCHours()+i.getUTCMinutes()+a,h=this.mod(Math.floor(n/60),24),r="12h"==s.toLowerCase()?this.mod(h-1,12)+1:this.twoDigits(h),o=this.twoDigits(Math.trunc(this.mod(n,60))),u="12H"==s?["AM","PM"][h<12?0:1]:"";return r+":"+o+(u?" "+u:"")}twoDigits(t){return String(t).padStart(2,"0")}value(t){return+String(t).split(/[^0-9.+-]/)[0]}isMin(t){return-1!=String(t).indexOf("min")}mod(t,s){return(t%s+s)%s}dtr=t=>t*Math.PI/180;rtd=t=>180*t/Math.PI;sin=t=>Math.sin(this.dtr(t));cos=t=>Math.cos(this.dtr(t));tan=t=>Math.tan(this.dtr(t));arcsin=t=>this.rtd(Math.asin(t));arccos=t=>this.rtd(Math.acos(t));arctan=t=>this.rtd(Math.atan(t));arccot=t=>this.rtd(Math.atan(1/t));arctan2=(t,s)=>this.rtd(Math.atan2(t,s))}"undefined"!=typeof module&&module.exports&&(module.exports={PrayTime:PrayTime});