Created
July 27, 2023 06:02
-
-
Save XTRAXTREME/68ed00e13f271854f12bad445e85630a to your computer and use it in GitHub Desktop.
Azan Prayer Time
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div style="width: 18rem;" class=" list-group"> | |
<button type="button" class="list-group-item list-group-item-action active"> | |
Prayer Time | |
</button> | |
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function PrayTimes(method) { | |
//------------------------ Constants -------------------------- | |
var // Time Names | |
timeNames = { | |
imsak: "Imsak", | |
fajr: "Fajr", | |
sunrise: "Sunrise", | |
dhuhr: "Dhuhr", | |
asr: "Asr", | |
sunset: "Sunset", | |
maghrib: "Maghrib", | |
isha: "Isha", | |
midnight: "Midnight" | |
}, | |
// Calculation Methods | |
methods = { | |
MWL: { | |
name: "Muslim World League", | |
params: { fajr: 18, isha: 17 } | |
}, | |
ISNA: { | |
name: "Islamic Society of North America (ISNA)", | |
params: { fajr: 15, isha: 15 } | |
}, | |
Egypt: { | |
name: "Egyptian General Authority of Survey", | |
params: { fajr: 19.5, isha: 17.5 } | |
}, | |
Makkah: { | |
name: "Umm Al-Qura University, Makkah", | |
params: { fajr: 18.5, isha: "90 min" } | |
}, // fajr was 19 degrees before 1430 hijri | |
Karachi: { | |
name: "University of Islamic Sciences, Karachi", | |
params: { fajr: 18, isha: 18 } | |
}, | |
Tehran: { | |
name: "Institute of Geophysics, University of Tehran", | |
params: { fajr: 17.7, isha: 14, maghrib: 4.5, midnight: "Jafari" } | |
}, // isha is not explicitly specified in this method | |
Jafari: { | |
name: "Shia Ithna-Ashari, Leva Institute, Qum", | |
params: { fajr: 16, isha: 14, maghrib: 4, midnight: "Jafari" } | |
} | |
}, | |
// Default Parameters in Calculation Methods | |
defaultParams = { | |
maghrib: "0 min", | |
midnight: "Standard" | |
}, | |
//----------------------- Parameter Values ---------------------- | |
/* | |
// Asr Juristic Methods | |
asrJuristics = [ | |
'Standard', // Shafi`i, Maliki, Ja`fari, Hanbali | |
'Hanafi' // Hanafi | |
], | |
// Midnight Mode | |
midnightMethods = [ | |
'Standard', // Mid Sunset to Sunrise | |
'Jafari' // Mid Sunset to Fajr | |
], | |
// Adjust Methods for Higher Latitudes | |
highLatMethods = [ | |
'NightMiddle', // middle of night | |
'AngleBased', // angle/60th of night | |
'OneSeventh', // 1/7th of night | |
'None' // No adjustment | |
], | |
// Time Formats | |
timeFormats = [ | |
'24h', // 24-hour format | |
'12h', // 12-hour format | |
'12hNS', // 12-hour format with no suffix | |
'Float' // floating point number | |
], | |
*/ | |
//---------------------- Default Settings -------------------- | |
calcMethod = "MWL", | |
// do not change anything here; use adjust method instead | |
setting = { | |
imsak: "10 min", | |
dhuhr: "0 min", | |
asr: "Standard", | |
highLats: "NightMiddle" | |
}, | |
timeFormat = "24h", | |
timeSuffixes = ["am", "pm"], | |
invalidTime = "-----", | |
numIterations = 1, | |
offset = {}, | |
//----------------------- Local Variables --------------------- | |
lat, | |
lng, | |
elv, // coordinates | |
timeZone, | |
jDate; // time variables | |
//---------------------- Initialization ----------------------- | |
// set methods defaults | |
var defParams = defaultParams; | |
for (var i in methods) { | |
var params = methods[i].params; | |
for (var j in defParams) | |
if (typeof params[j] == "undefined") params[j] = defParams[j]; | |
} | |
// initialize settings | |
calcMethod = methods[method] ? method : calcMethod; | |
var params = methods[calcMethod].params; | |
for (var id in params) setting[id] = params[id]; | |
// init time offsets | |
for (var i in timeNames) offset[i] = 0; | |
//----------------------- Public Functions ------------------------ | |
return { | |
// set calculation method | |
setMethod: function(method) { | |
if (methods[method]) { | |
this.adjust(methods[method].params); | |
calcMethod = method; | |
} | |
}, | |
// set calculating parameters | |
adjust: function(params) { | |
for (var id in params) setting[id] = params[id]; | |
}, | |
// set time offsets | |
tune: function(timeOffsets) { | |
for (var i in timeOffsets) offset[i] = timeOffsets[i]; | |
}, | |
// get current calculation method | |
getMethod: function() { | |
return calcMethod; | |
}, | |
// get current setting | |
getSetting: function() { | |
return setting; | |
}, | |
// get current time offsets | |
getOffsets: function() { | |
return offset; | |
}, | |
// get default calc parametrs | |
getDefaults: function() { | |
return methods; | |
}, | |
// return prayer times for a given date | |
getTimes: function(date, coords, timezone, dst, format) { | |
lat = 1 * coords[0]; | |
lng = 1 * coords[1]; | |
elv = coords[2] ? 1 * coords[2] : 0; | |
timeFormat = format || timeFormat; | |
if (date.constructor === Date) | |
date = [date.getFullYear(), date.getMonth() + 1, date.getDate()]; | |
if (typeof timezone == "undefined" || timezone == "auto") | |
timezone = this.getTimeZone(date); | |
if (typeof dst == "undefined" || dst == "auto") dst = this.getDst(date); | |
timeZone = 1 * timezone + (1 * dst ? 1 : 0); | |
jDate = this.julian(date[0], date[1], date[2]) - lng / (15 * 24); | |
return this.computeTimes(); | |
}, | |
// convert float time to the given format (see timeFormats) | |
getFormattedTime: function(time, format, suffixes) { | |
if (isNaN(time)) return invalidTime; | |
if (format == "Float") return time; | |
suffixes = suffixes || timeSuffixes; | |
time = DMath.fixHour(time + 0.5 / 60); // add 0.5 minutes to round | |
var hours = Math.floor(time); | |
var minutes = Math.floor((time - hours) * 60); | |
var suffix = format == "12h" ? suffixes[hours < 12 ? 0 : 1] : ""; | |
var hour = | |
format == "24h" | |
? this.twoDigitsFormat(hours) | |
: (hours + 12 - 1) % 12 + 1; | |
return ( | |
hour + | |
":" + | |
this.twoDigitsFormat(minutes) + | |
(suffix ? " " + suffix : "") | |
); | |
}, | |
//---------------------- Calculation Functions ----------------------- | |
// compute mid-day time | |
midDay: function(time) { | |
var eqt = this.sunPosition(jDate + time).equation; | |
var noon = DMath.fixHour(12 - eqt); | |
return noon; | |
}, | |
// compute the time at which sun reaches a specific angle below horizon | |
sunAngleTime: function(angle, time, direction) { | |
var decl = this.sunPosition(jDate + time).declination; | |
var noon = this.midDay(time); | |
var t = | |
1 / | |
15 * | |
DMath.arccos( | |
(-DMath.sin(angle) - DMath.sin(decl) * DMath.sin(lat)) / | |
(DMath.cos(decl) * DMath.cos(lat)) | |
); | |
return noon + (direction == "ccw" ? -t : t); | |
}, | |
// compute asr time | |
asrTime: function(factor, time) { | |
var decl = this.sunPosition(jDate + time).declination; | |
var angle = -DMath.arccot(factor + DMath.tan(Math.abs(lat - decl))); | |
return this.sunAngleTime(angle, time); | |
}, | |
// compute declination angle of sun and equation of time | |
// Ref: http://aa.usno.navy.mil/faq/docs/SunApprox.php | |
sunPosition: function(jd) { | |
var D = jd - 2451545.0; | |
var g = DMath.fixAngle(357.529 + 0.98560028 * D); | |
var q = DMath.fixAngle(280.459 + 0.98564736 * D); | |
var L = DMath.fixAngle( | |
q + 1.915 * DMath.sin(g) + 0.02 * DMath.sin(2 * g) | |
); | |
var R = 1.00014 - 0.01671 * DMath.cos(g) - 0.00014 * DMath.cos(2 * g); | |
var e = 23.439 - 0.00000036 * D; | |
var RA = DMath.arctan2(DMath.cos(e) * DMath.sin(L), DMath.cos(L)) / 15; | |
var eqt = q / 15 - DMath.fixHour(RA); | |
var decl = DMath.arcsin(DMath.sin(e) * DMath.sin(L)); | |
return { declination: decl, equation: eqt }; | |
}, | |
// convert Gregorian date to Julian day | |
// Ref: Astronomical Algorithms by Jean Meeus | |
julian: function(year, month, day) { | |
if (month <= 2) { | |
year -= 1; | |
month += 12; | |
} | |
var A = Math.floor(year / 100); | |
var B = 2 - A + Math.floor(A / 4); | |
var JD = | |
Math.floor(365.25 * (year + 4716)) + | |
Math.floor(30.6001 * (month + 1)) + | |
day + | |
B - | |
1524.5; | |
return JD; | |
}, | |
//---------------------- Compute Prayer Times ----------------------- | |
// compute prayer times at given julian date | |
computePrayerTimes: function(times) { | |
times = this.dayPortion(times); | |
var params = setting; | |
var imsak = this.sunAngleTime( | |
this.eval(params.imsak), | |
times.imsak, | |
"ccw" | |
); | |
var fajr = this.sunAngleTime(this.eval(params.fajr), times.fajr, "ccw"); | |
var sunrise = this.sunAngleTime( | |
this.riseSetAngle(), | |
times.sunrise, | |
"ccw" | |
); | |
var dhuhr = this.midDay(times.dhuhr); | |
var asr = this.asrTime(this.asrFactor(params.asr), times.asr); | |
var sunset = this.sunAngleTime(this.riseSetAngle(), times.sunset); | |
var maghrib = this.sunAngleTime(this.eval(params.maghrib), times.maghrib); | |
var isha = this.sunAngleTime(this.eval(params.isha), times.isha); | |
return { | |
imsak: imsak, | |
fajr: fajr, | |
sunrise: sunrise, | |
dhuhr: dhuhr, | |
asr: asr, | |
sunset: sunset, | |
maghrib: maghrib, | |
isha: isha | |
}; | |
}, | |
// compute prayer times | |
computeTimes: function() { | |
// default times | |
var times = { | |
imsak: 5, | |
fajr: 5, | |
sunrise: 6, | |
dhuhr: 12, | |
asr: 13, | |
sunset: 18, | |
maghrib: 18, | |
isha: 18 | |
}; | |
// main iterations | |
for (var i = 1; i <= numIterations; i++) | |
times = this.computePrayerTimes(times); | |
times = this.adjustTimes(times); | |
// add midnight time | |
times.midnight = | |
setting.midnight == "Jafari" | |
? times.sunset + this.timeDiff(times.sunset, times.fajr) / 2 | |
: times.sunset + this.timeDiff(times.sunset, times.sunrise) / 2; | |
times = this.tuneTimes(times); | |
return this.modifyFormats(times); | |
}, | |
// adjust times | |
adjustTimes: function(times) { | |
var params = setting; | |
for (var i in times) times[i] += timeZone - lng / 15; | |
if (params.highLats != "None") times = this.adjustHighLats(times); | |
if (this.isMin(params.imsak)) | |
times.imsak = times.fajr - this.eval(params.imsak) / 60; | |
if (this.isMin(params.maghrib)) | |
times.maghrib = times.sunset + this.eval(params.maghrib) / 60; | |
if (this.isMin(params.isha)) | |
times.isha = times.maghrib + this.eval(params.isha) / 60; | |
times.dhuhr += this.eval(params.dhuhr) / 60; | |
return times; | |
}, | |
// get asr shadow factor | |
asrFactor: function(asrParam) { | |
var factor = { Standard: 1, Hanafi: 2 }[asrParam]; | |
return factor || this.eval(asrParam); | |
}, | |
// return sun angle for sunset/sunrise | |
riseSetAngle: function() { | |
//var earthRad = 6371009; // in meters | |
//var angle = DMath.arccos(earthRad/(earthRad+ elv)); | |
var angle = 0.0347 * Math.sqrt(elv); // an approximation | |
return 0.833 + angle; | |
}, | |
// apply offsets to the times | |
tuneTimes: function(times) { | |
for (var i in times) times[i] += offset[i] / 60; | |
return times; | |
}, | |
// convert times to given time format | |
modifyFormats: function(times) { | |
for (var i in times) | |
times[i] = this.getFormattedTime(times[i], timeFormat); | |
return times; | |
}, | |
// adjust times for locations in higher latitudes | |
adjustHighLats: function(times) { | |
var params = setting; | |
var nightTime = this.timeDiff(times.sunset, times.sunrise); | |
times.imsak = this.adjustHLTime( | |
times.imsak, | |
times.sunrise, | |
this.eval(params.imsak), | |
nightTime, | |
"ccw" | |
); | |
times.fajr = this.adjustHLTime( | |
times.fajr, | |
times.sunrise, | |
this.eval(params.fajr), | |
nightTime, | |
"ccw" | |
); | |
times.isha = this.adjustHLTime( | |
times.isha, | |
times.sunset, | |
this.eval(params.isha), | |
nightTime | |
); | |
times.maghrib = this.adjustHLTime( | |
times.maghrib, | |
times.sunset, | |
this.eval(params.maghrib), | |
nightTime | |
); | |
return times; | |
}, | |
// adjust a time for higher latitudes | |
adjustHLTime: function(time, base, angle, night, direction) { | |
var portion = this.nightPortion(angle, night); | |
var timeDiff = | |
direction == "ccw" | |
? this.timeDiff(time, base) | |
: this.timeDiff(base, time); | |
if (isNaN(time) || timeDiff > portion) | |
time = base + (direction == "ccw" ? -portion : portion); | |
return time; | |
}, | |
// the night portion used for adjusting times in higher latitudes | |
nightPortion: function(angle, night) { | |
var method = setting.highLats; | |
var portion = 1 / 2; // MidNight | |
if (method == "AngleBased") portion = 1 / 60 * angle; | |
if (method == "OneSeventh") portion = 1 / 7; | |
return portion * night; | |
}, | |
// convert hours to day portions | |
dayPortion: function(times) { | |
for (var i in times) times[i] /= 24; | |
return times; | |
}, | |
//---------------------- Time Zone Functions ----------------------- | |
// get local time zone | |
getTimeZone: function(date) { | |
var year = date[0]; | |
var t1 = this.gmtOffset([year, 0, 1]); | |
var t2 = this.gmtOffset([year, 6, 1]); | |
return Math.min(t1, t2); | |
}, | |
// get daylight saving for a given date | |
getDst: function(date) { | |
return 1 * (this.gmtOffset(date) != this.getTimeZone(date)); | |
}, | |
// GMT offset for a given date | |
gmtOffset: function(date) { | |
var localDate = new Date(date[0], date[1] - 1, date[2], 12, 0, 0, 0); | |
var GMTString = localDate.toGMTString(); | |
var GMTDate = new Date( | |
GMTString.substring(0, GMTString.lastIndexOf(" ") - 1) | |
); | |
var hoursDiff = (localDate - GMTDate) / (1000 * 60 * 60); | |
return hoursDiff; | |
}, | |
//---------------------- Misc Functions ----------------------- | |
// convert given string into a number | |
eval: function(str) { | |
return 1 * (str + "").split(/[^0-9.+-]/)[0]; | |
}, | |
// detect if input contains 'min' | |
isMin: function(arg) { | |
return (arg + "").indexOf("min") != -1; | |
}, | |
// compute the difference between two times | |
timeDiff: function(time1, time2) { | |
return DMath.fixHour(time2 - time1); | |
}, | |
// add a leading 0 if necessary | |
twoDigitsFormat: function(num) { | |
return num < 10 ? "0" + num : num; | |
} | |
}; | |
} | |
//---------------------- Degree-Based Math Class ----------------------- | |
var DMath = { | |
dtr: function(d) { | |
return d * Math.PI / 180.0; | |
}, | |
rtd: function(r) { | |
return r * 180.0 / Math.PI; | |
}, | |
sin: function(d) { | |
return Math.sin(this.dtr(d)); | |
}, | |
cos: function(d) { | |
return Math.cos(this.dtr(d)); | |
}, | |
tan: function(d) { | |
return Math.tan(this.dtr(d)); | |
}, | |
arcsin: function(d) { | |
return this.rtd(Math.asin(d)); | |
}, | |
arccos: function(d) { | |
return this.rtd(Math.acos(d)); | |
}, | |
arctan: function(d) { | |
return this.rtd(Math.atan(d)); | |
}, | |
arccot: function(x) { | |
return this.rtd(Math.atan(1 / x)); | |
}, | |
arctan2: function(y, x) { | |
return this.rtd(Math.atan2(y, x)); | |
}, | |
fixAngle: function(a) { | |
return this.fix(a, 360); | |
}, | |
fixHour: function(a) { | |
return this.fix(a, 24); | |
}, | |
fix: function(a, b) { | |
a = a - b * Math.floor(a / b); | |
return a < 0 ? a + b : a; | |
} | |
}; | |
/*----------------------html------------------*/ | |
let time = []; | |
let date = new Date(); | |
//tz = time zone | |
tz = date | |
.toTimeString() | |
.split(" ")[1] | |
.split("+")[1]; | |
//console.log(date) | |
// instantiate prayerTime | |
var prayTimes = new PrayTimes(); | |
/*set default method to ISNA = Islamic Society of North America | |
*/ | |
prayTimes.setMethod("ISNA"); | |
//console.log(Object.keys()) | |
let lat, lng; | |
function init() { | |
if (navigator.geolocation) { | |
navigator.geolocation.getCurrentPosition(pos => { | |
lat = pos.coords.latitude; | |
lng = pos.coords.longitude; | |
//console.log(lat, lng); | |
pTime = prayTimes.getTimes(new Date(), [lat, lng], tz / 100); | |
for (i in pTime) { | |
time.push(pTime[i]); | |
} | |
let name = Object.keys(pTime); | |
name = name.splice(1, 7); | |
time = time.splice(1, 7); | |
// console.log(time) | |
let item = []; | |
x = name | |
.map((x, i) => { | |
return `<li class="list-group-item d-flex justify-content-between align-items-center"> | |
${x} | |
<span class="badge badge-primary badge-pill"> ${time[i]}</span> | |
</li> | |
`; | |
}) | |
.join(""); | |
document.querySelector(".list-group").innerHTML += x; | |
}); | |
} else { | |
console.log("your browser doesnt support geolocation"); | |
} | |
} | |
init(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.card, .list-group{ | |
margin: 10% auto; | |
} | |
.list-group-item{ | |
text-transform: capitalize; | |
} | |
.active{ | |
text-align: center; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment