Last active
October 18, 2018 15:46
-
-
Save birdbrainiac/dee8ff58d889cb83ba1624bf6c25f804 to your computer and use it in GitHub Desktop.
[roll20 Easter Calculator] A script to calculate the date of easter sunday, and also the day of the week for any given year, month, and day. The output isnt polished, it's simply presented as a proof of concept for now. #roll20 #roll20script
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
/* | |
Easter date Calculation | |
best easter calculator: https://www.staff.science.uu.nl/~gent0113/easter/easter_text2a.htm | |
script: https://www.staff.science.uu.nl/~gent0113/easter/addfiles/easter.js | |
root: https://www.staff.science.uu.nl/~gent0113/easter/eastercalculator.htm | |
historical easters: http://www.kevinlaughery.com/east4099.html | |
USAGE | |
!easter [year] [optional: true for gregorian calendar, false for julian] | |
gives the date of easter, and the date of paschal full moon, the full moon that immediately precedes easter sunday. | |
Paschal full moon can vary from the actual full moon date: full moon can sometimes occur in different days in different tiem zones | |
so back in 326 AD, the church came up with a way of calculating a standardised full moon date, which would be universal across the globe. | |
!easter 1805 | |
!easter 1805 true | |
!weekday [year] [month] [day] [optional: true for gregorian calendar, false for julian] | |
given a year, month, and day, !weekday tells what day of the week it is (Sunday, Monday, etc.) | |
!weekday 1805 11 29 | |
!weekday 1805 11 29 true | |
I set julian calendar as default for these, because most people (me included) will usually be using this | |
in historical or fantasy campaigns where julian is most appropriate. | |
The output isnt polished, it's simply presented as a proof of concept for now. | |
*/ | |
var easterMoon = easterMoon || (function () { | |
'use strict'; | |
const version = '0.1', | |
scriptName = 'Easter Moon', | |
lastUpdate = 1539862639541, //enter Date.now() in console to get the date | |
months = ['January','February','March','April','May','June','July','August','September','October','November','December'], | |
days = ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'], | |
checkInstall = () => { | |
log(`-=> ${scriptName} v${version} <=- [${new Date(lastUpdate)}]`); | |
}, | |
handleInput = (msg) => { | |
// copy the body of your on(chat:message) event to this function | |
if (msg.type === 'api' && msg.content.split(' ')[0] === '!easter' ) { | |
let args = msg.content.split(' '); | |
// args = !easter year gregorian/true/false | |
let year = parseInt(args[1],10) || 2018; | |
let easterDate = {}; | |
let moonday = ''; | |
if(args.length > 2 && args[2].toString().toLowerCase() == 'true') { | |
log('gregorian'); | |
easterDate = easterG(year); | |
moonday = weekday(year,easterDate.moon_month,easterDate.moon_day,true); | |
} else { | |
easterDate = easterJ(year); | |
moonday = weekday(year,easterDate.moon_month,easterDate.moon_day); | |
} | |
sendChat('',`Easter in ${year} falls on the ${easterDate.day}${ordinal(easterDate.day)} of ${months[easterDate.month -1]}.`); | |
sendChat('',`Paschal Full Moon in ${year} fell on ${moonday}, the ${easterDate.moon_day}${ordinal(easterDate.moon_day)} of ${months[easterDate.moon_month -1]}.`); | |
} else if (msg.type === 'api' && msg.content.split(' ')[0] === '!weekday' ) { | |
let args = msg.content.split(' '); | |
if (args.length <4) { | |
sendChat('', 'Too Few Arguments'); | |
return; | |
} | |
let year = parseInt(args[1],10) || 2018; | |
let month = parseInt(args[2],10) || 2018; | |
let day = parseInt(args[3],10) || 2018; | |
let calendar = false; | |
if(args.length > 4) { | |
if(args[4].toString().toLowerCase() === 'true') calendar = true; | |
} | |
let thisday = weekday(year,month,day,calendar); | |
sendChat('',`The ${day}${ordinal(day)} of ${months[month -1]} in ${year} is a ${thisday}.`); | |
} | |
}, | |
ordinal = (day) => { | |
switch(day) { | |
case 1: | |
case 21: | |
case 31: | |
return 'st'; | |
case 2: | |
case 22: | |
return 'nd'; | |
case 3: | |
case 23: | |
return 'rd'; | |
default: | |
return 'th'; | |
} | |
}, | |
gmod = (m,n) => { | |
// generalized modulo function (m mod n) - also valid for negative values of m | |
return ((m%n)+n)%n; | |
}, | |
weekday = (year,month,day,gregorian) => { | |
if(gregorian === undefined) gregorian = false; | |
let a = gmod(year,100); | |
let b = Math.floor(a/4); | |
const monthKey = [1,4,4,0,2,5,0,3,6,1,4,6]; | |
let c= b + day + monthKey[month-1]; | |
if(1 === yearType(year,(gregorian ? 'g': 'j')) && month < 3) { | |
c -= 1; | |
} | |
let d = c; | |
if(gregorian) { | |
d += [6,4,2,0][gmod(Math.floor(year/100),4)]; | |
} else { | |
d += 18 - Math.floor(year/100); | |
} | |
let e = d+ a; | |
let f = gmod(e,7); | |
log(`a ${a}; b ${b}; c ${c}; d ${d}; e ${e}; f ${f}.`); | |
return days[gmod(f -2,7)]; | |
}, | |
yearType = (year,cal) => { | |
// determine year type (yt=0 for common; yt=1 for bissextile) for Julian calendar (cal='j') or Gregorian calendar (cal='g') | |
let yt=0; | |
if(gmod(year,4) == 0) yt=1; | |
if(cal == 'g'){ | |
if(gmod(year,400) == 0) yt=1; | |
else if(gmod(year,100) == 0) yt=0; | |
} | |
return yt; | |
}, | |
easterJ = (year, emod) => { | |
//emod = 0 or 1, dionysian or armenian | |
if (emod === undefined) emod = 1; | |
let a = gmod(year,19); | |
let gn = a + 1; | |
let b = gmod (year, 4); | |
let c = gmod(year, 7); | |
let d = gmod((19 * a + 15), 30); | |
if (emod === 1 && gn === 1) d += 1; | |
let e = gmod((2 * b + 4 * c - d +6), 7); | |
let moon = d+= 113; | |
let sunday = moon + e +1; | |
let fm_month = Math.floor(moon/31); | |
let fm_day = gmod(moon,31) +1; | |
let month = Math.floor(sunday / 31); | |
let day = gmod(sunday,31) +1; | |
let output = {year: year, sunday: sunday, month: month, day: day, moon: moon, moon_month: fm_month, moon_day: fm_day}; | |
return output; | |
}, | |
easterG = (year) => { | |
// Gregorian Easter Sunday date | |
let a=gmod(year,19); | |
let gn=a+1; // Golden Number | |
let b=Math.floor(year/100); | |
let c=gmod(year,100); | |
let d=Math.floor(b/4); | |
let e=gmod(b,4); | |
let f=Math.floor((b+8)/25); | |
let g=Math.floor((b-f+1)/3); | |
let h=gmod((19*a+b-d-g+15),30); | |
let i=Math.floor(c/4); | |
let k=gmod(c,4); | |
let l=gmod((2*e+2*i-h-k+4),7); | |
let m=Math.floor((a+11*h+22*l)/451); | |
let ep=gmod((11*a+8-b+d+Math.floor((8*b+13)/25)),30); | |
let moon = 0; | |
if(ep <= 23) moon=136-ep; // Easter full moon [days after -92 March] | |
else if((ep == 25) && (gn > 11)) moon=140; | |
else if((ep == 24) || (ep == 25)) moon=141; | |
else if(ep >= 26) moon=166-ep; | |
let sunday=114+h-7*m+l; // Easter Sunday [days after -92 March] | |
let fm_month=Math.floor(moon/31); // month Easter full moon [March = 3; April = 4] | |
let fm_day=gmod(moon,31)+1; // day Easter full moon | |
let month=Math.floor(sunday/31); // month Easter Sunday [March = 3; April = 4] | |
let day=gmod(sunday,31)+1; // day Easter Sunday | |
let output = {year: year, sunday: sunday, month: month, day: day, moon: moon, moon_month: fm_month, moon_day: fm_day}; | |
return output; | |
}, | |
registerEventHandlers = function () { | |
on('chat:message', handleInput); | |
}; | |
return { | |
CheckInstall: checkInstall, | |
RegisterEventHandlers: registerEventHandlers | |
}; | |
}()); | |
on('ready', function () { | |
'use strict'; | |
easterMoon.CheckInstall(); | |
easterMoon.RegisterEventHandlers(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment