From 4403cb224c2cc593e68dd4b8e6f181b214fd5e77 Mon Sep 17 00:00:00 2001 From: Ali Camarata Date: Fri, 21 Jun 2024 20:14:18 -0400 Subject: [PATCH] Added MSC Method --- README.md | 21 ++++++++--- getMSC.js | 95 +++++++++++++++++++++++++++++++++++++++++++++++ getTimesAll.js | 10 +++++ package-lock.json | 4 +- package.json | 2 +- test.js | 11 +++--- 6 files changed, 129 insertions(+), 14 deletions(-) create mode 100644 getMSC.js diff --git a/README.md b/README.md index a50cd88..2dfb4ca 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,14 @@ Prayer times calculator using nrel-spa and custom formula for Fajr and Isha angles (as well as traditional static angle methods in the All function). +## Version 1.5 + +With the release of version 1.5, we have integrated the MoonSighting (MSC) method. The MSC method is unique in its dynamic adjustment for latitude and seasonal variations, and it is well-researched and widely respected. While our custom method is still in development, the MSC method’s integration marks a significant enhancement. + +Our MSC implementation will have some accuracy improvement though due to using nrel-spa as the base calculations over other the more common but less accurate suncalc package or others. With that said the MSC method is imported as is and does not account for elevation for angle perspective adjustment (major) nor temperature, pressure, and weather for the atmospheric refraction (minor) variables that we have included. + +With some work we can incorporate all improvements from our method along with MSC's logic as well as these additional variables and come to something that is more accurate and more dynamic than currently available online anywhere in future versions, inshaa' Allah. + ## Installation ```bash @@ -14,21 +22,21 @@ npm install pray-calc Example of using pray-calc to get prayer times: ```js -const { getTimes, calcTimesAll } = require('pray-calc'); +const { getTimes, calcTimesAll } = require('./index'); -const date = new Date(); +// Manually setting the date to January 1, 2024 +const date = new Date('2024-01-01T00:00:00Z'); -/* NYC - minimum params +// NYC - minimum params const city = "New York" const lat = 40.7128; const lng = -74.006; -const tz = null +const tz = -5 const elevation = null const temperature = null const pressure = null -*/ -// Jakarta - all params +/* Jakarta - all params const city = "Jakarta" const lat = -6.2088 const lng = 106.8456 @@ -36,6 +44,7 @@ const tz = 7 const elevation = 18 const temperature = 26.56 const pressure = 1017 +*/ // Get results const get = getTimes(date, lat, lng); // minimal args diff --git a/getMSC.js b/getMSC.js new file mode 100644 index 0000000..bc3039b --- /dev/null +++ b/getMSC.js @@ -0,0 +1,95 @@ +// getMSC.js +class PrayerTimes { + constructor(date, latitude) { + this.date = new Date(date); + this.latitude = latitude; + this.getDyy(); + } + + getDyy() { + const year = this.date.getFullYear(); + const northDate = new Date(`${year}-12-21`); + const southDate = new Date(`${year}-06-21`); + const zeroDate = this.latitude > 0 ? northDate : southDate; + this.dyy = Math.floor((this.date - zeroDate) / (1000 * 60 * 60 * 24)); + if (this.dyy < 0) { + this.dyy += 365; + } + } + + getMinutes() { + if (this.dyy < 91) + return this.a + ((this.b - this.a) / 91) * this.dyy; + if (this.dyy < 137) + return this.b + ((this.c - this.b) / 46) * (this.dyy - 91); + if (this.dyy < 183) + return this.c + ((this.d - this.c) / 46) * (this.dyy - 137); + if (this.dyy < 229) + return this.d + ((this.c - this.d) / 46) * (this.dyy - 183); + if (this.dyy < 275) + return this.c + ((this.b - this.c) / 46) * (this.dyy - 229); + return this.b + ((this.a - this.b) / 91) * (this.dyy - 275); + } +} + +class Fajr extends PrayerTimes { + constructor(date, latitude) { + super(date, latitude); + this.a = 75 + (28.65 / 55) * Math.abs(latitude); + this.b = 75 + (19.44 / 55) * Math.abs(latitude); + this.c = 75 + (32.74 / 55) * Math.abs(latitude); + this.d = 75 + (48.1 / 55) * Math.abs(latitude); + } + + getMinutesBeforeSunrise() { + return Math.round(this.getMinutes()); + } +} + +class Isha extends PrayerTimes { + static SHAFAQ_AHMER = 'ahmer'; + static SHAFAQ_ABYAD = 'abyad'; + static SHAFAQ_GENERAL = 'general'; + + constructor(date, latitude, shafaq = Isha.SHAFAQ_GENERAL) { + super(date, latitude); + this.setShafaq(shafaq); + } + + setShafaq(shafaq) { + this.shafaq = shafaq; + + if (shafaq === Isha.SHAFAQ_AHMER) { + this.a = 62 + (17.4 / 55) * Math.abs(this.latitude); + this.b = 62 - (7.16 / 55) * Math.abs(this.latitude); + this.c = 62 + (5.12 / 55) * Math.abs(this.latitude); + this.d = 62 + (19.44 / 55) * Math.abs(this.latitude); + } else if (shafaq === Isha.SHAFAQ_ABYAD) { + this.a = 75 + (25.6 / 55) * Math.abs(this.latitude); + this.b = 75 + (7.16 / 55) * Math.abs(this.latitude); + this.c = 75 + (36.84 / 55) * Math.abs(this.latitude); + this.d = 75 + (81.84 / 55) * Math.abs(this.latitude); + } else { + this.a = 75 + (25.6 / 55) * Math.abs(this.latitude); + this.c = 75 - (9.21 / 55) * Math.abs(this.latitude); + this.b = 75 + (2.05 / 55) * Math.abs(this.latitude); + this.d = 75 + (6.14 / 55) * Math.abs(this.latitude); + } + } + + getMinutesAfterSunset() { + return Math.round(this.getMinutes()); + } +} + +function getFajr(date, latitude) { + const fajr = new Fajr(date, latitude); + return fajr.getMinutesBeforeSunrise(); +} + +function getIsha(date, latitude, shafaq = Isha.SHAFAQ_GENERAL) { + const isha = new Isha(date, latitude, shafaq); + return isha.getMinutesAfterSunset(); +} + +module.exports = { getFajr, getIsha, Isha, Fajr }; \ No newline at end of file diff --git a/getTimesAll.js b/getTimesAll.js index a8e7a22..8d82e66 100644 --- a/getTimesAll.js +++ b/getTimesAll.js @@ -2,6 +2,7 @@ const { getSpa } = require('nrel-spa'); const { getAngles } = require('./getAngles'); const { getAsr } = require('./getAsr'); const { getQiyam } = require('./getQiyam'); +const { getFajr, getIsha } = require('./getMSC'); const methods = [ {n:'UOIF', f:12, i:12, r:'France'}, @@ -14,6 +15,7 @@ const methods = [ {n:'UAQ', f:18.5, i:18, r:'SA'}, {n:'Egypt', f:19.5, i:17.5, r:'Africa, SY, IQ, LB'}, {n:'MUIS', f:20, i:18, r:'SG'}, + {n:'MSC', f:null, i:null, r:'Global'}, ]; function getTimesAll(date, lat, lng, tz, elevation = 50, temperature = 15, pressure = 1013.25, standard = true) { @@ -70,6 +72,14 @@ function getTimesAll(date, lat, lng, tz, elevation = 50, temperature = 15, press if (method.n === 'UAQ') { ishaMethodTime = spaData.sunset + ((1 / 60) * 90); } + else if (method.n === 'MSC') { + // Calculate Fajr and Isha for MSC method + const fajrMSCMinutes = getFajr(date, lat); + const ishaMSCMinutes = getIsha(date, lat); + + fajrMethodTime = spaData.sunrise - ((1 / 60) * fajrMSCMinutes); + ishaMethodTime = spaData.sunset + ((1 / 60) * ishaMSCMinutes); + } prayerTimes.Methods[method.n] = [fajrMethodTime, ishaMethodTime]; }); diff --git a/package-lock.json b/package-lock.json index a359e1c..2bf9567 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pray-calc", - "version": "1.4.0", + "version": "1.5.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pray-calc", - "version": "1.4.0", + "version": "1.5.0", "license": "ISC", "dependencies": { "nrel-spa": "^1.2.2", diff --git a/package.json b/package.json index aac0627..e6658aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pray-calc", - "version": "1.4.1", + "version": "1.5.0", "description": "Prayer times calculator using nrel-spa and custom formula for Fajr and Isha angles (as well as traditional static angle methods in the All function)", "main": "index.js", "scripts": { diff --git a/test.js b/test.js index 396765b..a83e871 100644 --- a/test.js +++ b/test.js @@ -1,18 +1,18 @@ const { getTimes, calcTimesAll } = require('./index'); -const date = new Date(); +// Manually setting the date to January 1, 2024 +const date = new Date('2024-01-01T00:00:00Z'); -/* NYC - minimum params +// NYC - minimum params const city = "New York" const lat = 40.7128; const lng = -74.006; -const tz = null +const tz = -5 const elevation = null const temperature = null const pressure = null -*/ -// Jakarta - all params +/* Jakarta - all params const city = "Jakarta" const lat = -6.2088 const lng = 106.8456 @@ -20,6 +20,7 @@ const tz = 7 const elevation = 18 const temperature = 26.56 const pressure = 1017 +*/ // Get results const get = getTimes(date, lat, lng); // minimal args