Skip to content

Commit

Permalink
feat: adding the option to handle polar night and midnight sun cases
Browse files Browse the repository at this point in the history
  • Loading branch information
b-stud committed Dec 14, 2020
1 parent 5a38898 commit f7a1a9c
Show file tree
Hide file tree
Showing 9 changed files with 419 additions and 16 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules/
coverage/
coverage/
.idea
137 changes: 136 additions & 1 deletion Adhan.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Adhan.js.map

Large diffs are not rendered by default.

22 changes: 12 additions & 10 deletions src/Adhan.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@ import { Madhab } from './Madhab';
import HighLatitudeRule from './HighLatitudeRule';
import CalculationMethod from './CalculationMethod';
import CalculationParameters from './CalculationParameters';
import qibla from './Qibla';
import Qibla from './Qibla';
import SunnahTimes from './SunnahTimes';
import { PolarCircleResolution } from './PolarCircleResolution';

const adhan = {
Prayer: Prayer,
Madhab: Madhab,
HighLatitudeRule: HighLatitudeRule,
Coordinates: Coordinates,
CalculationParameters: CalculationParameters,
CalculationMethod: CalculationMethod,
PrayerTimes: PrayerTimes,
SunnahTimes: SunnahTimes,
Qibla: qibla
Prayer,
Madhab,
HighLatitudeRule,
Coordinates,
CalculationParameters,
CalculationMethod,
PrayerTimes,
SunnahTimes,
Qibla,
PolarCircleResolution,
};

export default adhan;
11 changes: 11 additions & 0 deletions src/CalculationParameters.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Madhab } from './Madhab';
import HighLatitudeRule from './HighLatitudeRule';
import { PolarCircleResolution } from './PolarCircleResolution';

export default class CalculationParameters {
constructor(methodName, fajrAngle, ishaAngle, ishaInterval, maghribAngle) {
Expand All @@ -12,6 +13,16 @@ export default class CalculationParameters {
this.highLatitudeRule = HighLatitudeRule.MiddleOfTheNight;
this.adjustments = { fajr: 0, sunrise: 0, dhuhr: 0, asr: 0, maghrib: 0, isha: 0 };
this.methodAdjustments = { fajr: 0, sunrise: 0, dhuhr: 0, asr: 0, maghrib: 0, isha: 0 };
this.polarCircleResolution = PolarCircleResolution.unresolved;
}

clone() {
const {
methodName, fajrAngle, ishaAngle, ishaInterval, maghribAngle, polarCircleResolution,
} = this;
const parameters = new CalculationParameters(methodName, fajrAngle, ishaAngle, ishaInterval, maghribAngle);
parameters.polarCircleResolution = polarCircleResolution;
return parameters;
}

nightPortions() {
Expand Down
4 changes: 4 additions & 0 deletions src/DateUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ export function dayOfYear(date) {

return returnedDayOfYear;
}

export function isValidDate(date) {
return date instanceof Date && !isNaN(date.valueOf());
}
74 changes: 74 additions & 0 deletions src/PolarCircleResolution.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { dateByAddingSeconds, dayOfYear, isValidDate } from './DateUtils';
import adhan from './Adhan';
import SolarTime from './SolarTime';
import Astronomical from './Astronomical';
import TimeComponents from './TimeComponents';

export const PolarCircleResolution = {
aqrabBalad: 'aqrab-balad',
aqrabYaum: 'aqrab-yaum',
unresolved: 'unresolved'
};

export const POLAR_CIRCLE_RESOLUTION_LATITUDE_VARIATION_STEP = 0.5; // Degrees to add/remove at each search step
export const POLAR_CIRCLE_RESOLUTION_VALID_LATITUDE = 65; // Based on https://en.wikipedia.org/wiki/Midnight_sun

const isValidSolarTime = (solarTime) => {
if (solarTime) {
return solarTime && !isNaN(solarTime.sunrise) && !isNaN(solarTime.sunset);
}
return false;
}

export const polarCircleResolvedValues = (resolver, date, coordinates) => {
let resolvedLatitude = coordinates.latitude;
let resolvedDate = new Date(date.getTime());
let resolvedSolarTime = null;
let daysAdded = 0;
let pastDate = ((date) => { const newDate = new Date(date.getTime()); newDate.setDate(date.getDate() - 1); return newDate; })(date);
let futureDate = ((date) => { const newDate = new Date(date.getTime()); newDate.setDate(date.getDate() + 1); return newDate; })(date);
let adjustedLatitude = coordinates.latitude;

switch (resolver) {
case PolarCircleResolution.aqrabYaum: {
while (!isValidSolarTime(resolvedSolarTime) && daysAdded <= Math.ceil(365 / 2)) { // Search within 6 months backward & forward
resolvedSolarTime = new SolarTime(pastDate, coordinates);
if (isValidSolarTime(resolvedSolarTime)) {
resolvedDate.setTime(pastDate.getTime());
} else {
resolvedSolarTime = new SolarTime(futureDate, coordinates);
if (isValidSolarTime(resolvedSolarTime)) {
resolvedDate.setTime(futureDate.getTime());
}
}
pastDate.setDate(pastDate.getDate() - 1);
futureDate.setDate(pastDate.getDate() + 1);
daysAdded++;
}
break;
}
default:
case PolarCircleResolution.aqrabBalad: {
while (!isValidSolarTime(resolvedSolarTime) && Math.abs(adjustedLatitude) >= POLAR_CIRCLE_RESOLUTION_VALID_LATITUDE) {
adjustedLatitude -= (Math.sign(adjustedLatitude) * POLAR_CIRCLE_RESOLUTION_LATITUDE_VARIATION_STEP);
resolvedSolarTime = new SolarTime(resolvedDate, {
...coordinates,
latitude: adjustedLatitude,
});
if (isValidSolarTime(resolvedSolarTime)) {
resolvedLatitude = adjustedLatitude;
}
}
break;
}
}

return {
coordinates: {
...coordinates,
latitude: resolvedLatitude,
},
date: resolvedDate,
solarTime: resolvedSolarTime,
};
}
Loading

0 comments on commit f7a1a9c

Please sign in to comment.