• # calendrical.calendar.conversions.js

• ```var Calendrical = (function(exports){
"use strict";

exports.calendar = exports.calendar || {};```
• Aliases

```  var astro    = exports.astro,
calendar = exports.calendar;```
• Is a given year in the Gregorian calendar a leap year?

```  calendar.leapGregorian = function(year) {
return ((year % 4) == 0) &&
(!(((year % 100) == 0) && ((year % 400) != 0)));
}```
• Determine Julian day number from Gregorian calendar date

```  calendar.gregorianToJd = function(year, month, day) {
return (this.constants.gregorian.EPOCH - 1) +
(365 * (year - 1)) +
Math.floor((year - 1) / 4) +
(-Math.floor((year - 1) / 100)) +
Math.floor((year - 1) / 400) +
Math.floor((((367 * month) - 362) / 12) +
((month <= 2) ? 0 :
(this.leapGregorian(year) ? -1 : -2)
) +
day);
}

calendar.jdToGregorianYear = function(jd) {
var wjd, depoch, quadricent, dqc, cent, dcent, quad, dquad,
yindex, year;

wjd        = Math.floor(jd - 0.5) + 0.5;
depoch     = wjd - this.constants.gregorian.EPOCH;
quadricent = Math.floor(depoch / 146097);
dqc        = astro.mod(depoch, 146097);
cent       = Math.floor(dqc / 36524);
dcent      = astro.mod(dqc, 36524);
quad       = Math.floor(dcent / 1461);
dquad      = astro.mod(dcent, 1461);
yindex     = Math.floor(dquad / 365);
year       = (quadricent * 400) + (cent * 100) + (quad * 4) + yindex;

if (!((cent == 4) || (yindex == 4))) { year++; }

return year;
}```
• Calculate Gregorian calendar date from Julian day

```  calendar.jdToGregorian = function(jd) {
var wjd, year, yearday, leapadj, month, day;

wjd = Math.floor(jd - 0.5) + 0.5;
year = this.jdToGregorianYear(jd);

yearday = wjd - this.gregorianToJd(year, 1, 1);
leapadj = ((wjd < this.gregorianToJd(year, 3, 1)) ? 0 :
(this.leapGregorian(year) ? 1 : 2)
);
month = Math.floor((((yearday + leapadj) * 12) + 373) / 367);
day   = (wjd - this.gregorianToJd(year, month, 1)) + 1;

return [year, month, day];
}```
• Return Julian day of given ISO year, week, and day

```  calendar.nWeeks = function(weekday, jd, nthweek) {
var j = 7 * nthweek;

if (nthweek > 0) {
j += this.previousWeekday(weekday, jd);
} else {
j += this.nextWeekday(weekday, jd);
}

return j;
}

calendar.isoToJulian = function(year, week, day) {
return day + this.nWeeks(0, this.gregorianToJd(year - 1, 12, 28), week);
}```
• Return array of ISO (year, week, day) for Julian day

```  calendar.jdToIso = function(jd) {
var year, week, day;

year = this.jdToGregorian(jd - 3);

if (jd >= this.isoToJulian(year + 1, 1, 1)) { year++; }

week = Math.floor((jd - this.isoToJulian(year, 1, 1)) / 7) + 1;
day  = astro.jwday(jd);

if (day == 0) { day = 7; }

return [year, week, day];
}```
• Return Julian day of given ISO year, and day of year

```  calendar.isoDayToJulian = function(year, day) {
return (day - 1) + this.gregorianToJd(year, 1, 1);
}```
• Return array of ISO (year, day_of_year) for Julian day

```  calendar.jdToIsoDay = function(jd) {
var year, day;

year = this.jdToGregorian(jd);
day = Math.floor(jd - this.gregorianToJd(year, 1, 1)) + 1;
return [year, day];
}```
• Pad a string to a given length with a given fill character.

```  calendar.pad = function(str, howlong, padwith) {
var s = str.toString();

while (s.length < howlong) {
s = padwith + s;
}

return s;
}```
• Determine Julian day number from Julian calendar date

```  calendar.leapJulian = function(year) {
return astro.mod(year, 4) == ((year > 0) ? 0 : 3);
}

calendar.julianToJd = function(year, month, day) {```
• Adjust negative common era years to the zero-based notation we use.

`    if (year < 1) { year++; }`
• Algorithm as given in Meeus, Astronomical Algorithms, Chapter 7, page 61

```    if (month <= 2) {
year--;
month += 12;
}

return ((Math.floor((365.25 * (year + 4716))) +
Math.floor((30.6001 * (month + 1))) +
day) - 1524.5);
}```
• Calculate Julian calendar date from Julian day

```  calendar.jdToJulian = function(td) {
var z, a, alpha, b, c, d, e, year, month, day;

td += 0.5;
z = Math.floor(td);

a = z;
b = a + 1524;
c = Math.floor((b - 122.1) / 365.25);
d = Math.floor(365.25 * c);
e = Math.floor((b - d) / 30.6001);

month = Math.floor((e < 14) ? (e - 1) : (e - 13));
year = Math.floor((month > 2) ? (c - 4716) : (c - 4715));
day = b - d - Math.floor(30.6001 * e);```
• If year is less than 1, subtract one to convert from a zero based date system to the common era system in which the year -1 (1 B.C.E) is followed by year 1 (1 C.E.).

```    if (year < 1) { year--; }

return [year, month, day];
}```
• Determine Julian day from Hebrew date

Is a given Hebrew year a leap year?

```  calendar.hebrewLeap = function(year) {
return astro.mod(((year * 7) + 1), 19) < 7;
}```
• How many months are there in a Hebrew year (12 = normal, 13 = leap)

```  calendar.hebrewYearMonths = function(year) {
return this.hebrewLeap(year) ? 13 : 12;
}```
• Test for delay of start of new year and to avoid Sunday, Wednesday, and Friday as start of the new year.

```  calendar.hebrewDelay1 = function(year) {
var months, day, parts;

months = Math.floor(((235 * year) - 234) / 19);
parts  = 12084 + (13753 * months);
day    = (months * 29) + Math.floor(parts / 25920);

if (astro.mod((3 * (day + 1)), 7) < 3) {
day++;
}

return day;
}```
• Check for delay in start of new year due to length of adjacent years

```  calendar.hebrewDelay2 = function(year) {
var last, present, next;

last    = this.hebrewDelay1(year - 1);
present = this.hebrewDelay1(year);
next    = this.hebrewDelay1(year + 1);

return ((next - present) == 356) ? 2 :
(((present - last) == 382) ? 1 : 0);
}```
• How many days are in a Hebrew year?

```  calendar.hebrewYearDays = function(year) {
return this.hebrewToJd(year + 1, 7, 1) - this.hebrewToJd(year, 7, 1);
}```
• How many days are in a given month of a given year

`  calendar.hebrewMonthDays = function(year, month) {`
• First of all, dispose of fixed-length 29 day months

```    if (month == 2 || month == 4 || month == 6 ||
month == 10 || month == 13) {
return 29;
}```
• If it's not a leap year, Adar has 29 days

```    if (month == 12 && !this.hebrewLeap(year)) {
return 29;
}```
• If it's Heshvan, days depend on length of year

```    if (month == 8 && !(astro.mod(this.hebrewYearDays(year), 10) == 5)) {
return 29;
}```
• Similarly, Kislev varies with the length of year

```    if (month == 9 && (astro.mod(this.hebrewYearDays(year), 10) == 3)) {
return 29;
}```
• Nope, it's a 30 day month

```    return 30;
}```
• Finally, wrap it all up into...

```  calendar.hebrewToJd = function(year, month, day) {
var jd, mon, months;

months = this.hebrewYearMonths(year);

jd = this.constants.hebrew.EPOCH + this.hebrewDelay1(year) +
this.hebrewDelay2(year) + day + 1;

if (month < 7) {
for (mon = 7; mon <= months; mon++) {
jd += this.hebrewMonthDays(year, mon);
}
for (mon = 1; mon < month; mon++) {
jd += this.hebrewMonthDays(year, mon);
}
} else {
for (mon = 7; mon < month; mon++) {
jd += this.hebrewMonthDays(year, mon);
}
}

return jd;
}```
• Convert Julian date to Hebrew date This works by making multiple calls to the inverse function, and is this very slow.

```  calendar.jdToHebrew = function(jd) {
var year, month, day, i, count, first;

jd    = Math.floor(jd) + 0.5;
count = Math.floor(((jd - this.constants.hebrew.EPOCH) * 98496.0) / 35975351.0);
year  = count - 1;

for (i = count; jd >= this.hebrewToJd(i, 7, 1); i++) {
year++;
}

first = (jd < this.hebrewToJd(year, 1, 1)) ? 7 : 1;
month = first;

for (i = first; jd > this.hebrewToJd(year, i, this.hebrewMonthDays(year, i)); i++) {
month++;
}

day = (jd - this.hebrewToJd(year, month, 1)) + 1;

return [year, month, day];
}```
• Determine Julian day and fraction of the September equinox at the Paris meridian in a given Gregorian year.

```  calendar.equinoxeAParis = function(year) {
var equJED, equJD, equAPP, equParis, dtParis;```
• September equinox in dynamical time

`    equJED = astro.equinox(year, 2);`
• Correct for delta T to obtain Universal time

`    equJD = equJED - (astro.deltat(year) / (24 * 60 * 60));`
• Apply the equation of time to yield the apparent time at Greenwich

`    equAPP = equJD + astro.equationOfTime(equJED);`
• Finally, we must correct for the constant difference between the Greenwich meridian and that of Paris, 2°20'15" to the East.

```    dtParis = (2 + (20 / 60.0) + (15 / (60 * 60.0))) / 360;
equParis = equAPP + dtParis;

return equParis;
}```
• Calculate Julian day during which the September equinox, reckoned from the Paris meridian, occurred for a given Gregorian year.

```  calendar.parisEquinoxeJd = function(year) {
var ep, epg;

ep  = this.equinoxeAParis(year);
epg = Math.floor(ep - 0.5) + 0.5;

return epg;
}```
• Determine the year in the French revolutionary calendar in which a given Julian day falls. Returns an array of two elements:

 Année de la Révolution  Julian day number containing equinox for this year.

```  calendar.anneeDaLaRevolution = function(jd) {
var guess = this.jdToGregorian(jd) - 2,
lasteq, nexteq, adr;

lasteq = this.parisEquinoxeJd(guess);

while (lasteq > jd) {
guess--;
lasteq = this.parisEquinoxeJd(guess);
}

nexteq = lasteq - 1;

while (!((lasteq <= jd) && (jd < nexteq))) {
lasteq = nexteq;
guess++;
nexteq = this.parisEquinoxeJd(guess);
}

adr = Math.round((lasteq - this.constants.french_revolutionary.EPOCH) /
astro.constants.TROPICAL_YEAR) + 1;

return [adr, lasteq];
}```
• Calculate date in the French Revolutionary calendar from Julian day. The five or six "sansculottides" are considered a thirteenth month in the results of this function.

```  calendar.jdToFrenchRevolutionary = function(jd) {
var an, mois, decade, jour,
adr, equinoxe;

jd       = Math.floor(jd) + 0.5;
adr      = this.anneeDaLaRevolution(jd);
an       = adr;
equinoxe = adr;
mois     = Math.floor((jd - equinoxe) / 30) + 1;
jour     = (jd - equinoxe) % 30;
decade   = Math.floor(jour / 10) + 1;
jour     = (jour % 10) + 1;

return [an, mois, decade, jour];
}```
• Obtain Julian day from a given French Revolutionary calendar date.

```  calendar.frenchRevolutionaryToJd = function(an, mois, decade, jour) {
var adr, equinoxe, guess, jd;

guess = this.constants.french_revolutionary.EPOCH + (astro.constants.TROPICAL_YEAR * ((an - 1) - 1));
adr = [an - 1, 0];

while (adr < an) {
adr = this.anneeDaLaRevolution(guess);
guess = adr + (astro.constants.TROPICAL_YEAR + 2);
}
equinoxe = adr;

jd = equinoxe + (30 * (mois - 1)) + (10 * (decade - 1)) + (jour - 1);
return jd;
}```
• Is a given year a leap year in the Islamic calendar?

```  calendar.leapIslamic = function(year) {
return (((year * 11) + 14) % 30) < 11;
}```
• Determine Julian day from Islamic date

```  calendar.islamicToJd = function(year, month, day) {
return (day +
Math.ceil(29.5 * (month - 1)) +
(year - 1) * 354 +
Math.floor((3 + (11 * year)) / 30) +
this.constants.islamic.EPOCH) - 1;
}```
• Calculate Islamic date from Julian day

```  calendar.jdToIslamic = function(jd) {
var year, month, day;

jd    = Math.floor(jd) + 0.5;
year  = Math.floor(((30 * (jd - this.constants.islamic.EPOCH)) + 10646) / 10631);
month = Math.min(12, Math.ceil((jd - (29 + this.islamicToJd(year, 1, 1))) / 29.5) + 1);
day   = (jd - this.islamicToJd(year, month, 1)) + 1;

return [year, month, day];
}```
• Determine Julian day and fraction of the March equinox at the Tehran meridian in a given Gregorian year.

```  calendar.tehranEquinox = function(year) {
var equJED, equJD, equAPP, equTehran, dtTehran;```
• March equinox in dynamical time

`    equJED = astro.equinox(year, 0);`
• Correct for delta T to obtain Universal time

`    equJD = equJED - (astro.deltat(year) / (24 * 60 * 60));`
• Apply the equation of time to yield the apparent time at Greenwich

`    equAPP = equJD + astro.equationOfTime(equJED);`
• Finally, we must correct for the constant difference between the Greenwich meridian andthe time zone standard for Iran Standard time, 52°30' to the East.

```    dtTehran  = (52 + (30 / 60.0) + (0 / (60.0 * 60.0))) / 360;
equTehran = equAPP + dtTehran;

return equTehran;
}```
• Calculate Julian day during which the March equinox, reckoned from the Tehran meridian, occurred for a given Gregorian year.

```  calendar.tehranEquinoxJd = function(year) {
var ep, epg;

ep  = this.tehranEquinox(year);
epg = Math.floor(ep);

return epg;
}```
• Determine the year in the Persian astronomical calendar in which a given Julian day falls. Returns an array of two elements:

 Persian year  Julian day number containing equinox for this year.

```  calendar.persianaYear = function(jd) {
var guess = this.jdToGregorian(jd) - 2,
lasteq, nexteq, adr;

lasteq = this.tehranEquinoxJd(guess);

while (lasteq > jd) {
guess--;
lasteq = this.tehranEquinoxJd(guess);
}

nexteq = lasteq - 1;

while (!((lasteq <= jd) && (jd < nexteq))) {
lasteq = nexteq;
guess++;
nexteq = this.tehranEquinoxJd(guess);
}

adr = Math.round((lasteq - this.constants.persian.EPOCH) /
astro.constants.TROPICAL_YEAR) + 1;

return [adr, lasteq];
}```
• Calculate date in the Persian astronomical calendar from Julian day.

```  calendar.jdToPersiana = function(jd) {
var year, month, day, adr, equinox, yday;

jd      = Math.floor(jd) + 0.5;
adr     = this.persianaYear(jd);
year    = adr;
equinox = adr;
day     = Math.floor((jd - equinox) / 30) + 1;

yday  = (Math.floor(jd) - this.persianaToJd(year, 1, 1)) + 1;
month = (yday <= 186) ? Math.ceil(yday / 31) : Math.ceil((yday - 6) / 30);
day   = (Math.floor(jd) - this.persianaToJd(year, month, 1)) + 1;

return [year, month, day];
}```
• Obtain Julian day from a given Persian astronomical calendar date.

```  calendar.persianaToJd = function(year, month, day) {
var adr, equinox, guess, jd;

guess = (this.constants.persian.EPOCH - 1) +
(astro.constants.TROPICAL_YEAR * ((year - 1) - 1));
adr   = [year - 1, 0];

while (adr < year) {
adr   = this.persianaYear(guess);
guess = adr + (astro.constants.TROPICAL_YEAR + 2);
}

equinox = adr;

jd = equinox +
((month <= 7) ?
((month - 1) * 31) :
(((month - 1) * 30) + 6)
) +
(day - 1);

return jd;
}```
• Is a given year a leap year in the Persian astronomical calendar?

```  calendar.leapPersiana = function(year) {
return (this.persianaToJd(year + 1, 1, 1) -
this.persianaToJd(year, 1, 1)) > 365;
}```
• Is a given year a leap year in the Persian calendar?

```  calendar.leapPersian = function(year) {
return ((((((year - ((year > 0) ? 474 : 473)) % 2820) + 474) + 38) * 682) % 2816) < 682;
}```
• Determine Julian day from Persian date

```  calendar.persianToJd = function(year, month, day) {
var epbase, epyear;

epbase = year - ((year >= 0) ? 474 : 473);
epyear = 474 + astro.mod(epbase, 2820);

return day +
((month <= 7) ?
((month - 1) * 31) :
(((month - 1) * 30) + 6)
) +
Math.floor(((epyear * 682) - 110) / 2816) +
(epyear - 1) * 365 +
Math.floor(epbase / 2820) * 1029983 +
(this.constants.persian.EPOCH - 1);
}```
• Calculate Persian date from Julian day

```  calendar.jdToPersian = function(jd) {
var year, month, day, depoch, cycle, cyear, ycycle,
aux1, aux2, yday;

jd = Math.floor(jd) + 0.5;

depoch = jd - this.persianToJd(475, 1, 1);
cycle  = Math.floor(depoch / 1029983);
cyear  = astro.mod(depoch, 1029983);

if (cyear == 1029982) {
ycycle = 2820;
} else {
aux1 = Math.floor(cyear / 366);
aux2 = astro.mod(cyear, 366);
ycycle = Math.floor(((2134 * aux1) + (2816 * aux2) + 2815) / 1028522) +
aux1 + 1;
}

year = ycycle + (2820 * cycle) + 474;

if (year <= 0) { year--; }

yday  = (jd - this.persianToJd(year, 1, 1)) + 1;
month = (yday <= 186) ? Math.ceil(yday / 31) : Math.ceil((yday - 6) / 30);
day   = (jd - this.persianToJd(year, month, 1)) + 1;

return [year, month, day];
}```
• Determine Julian day from Mayan long count

```  calendar.mayanCountToJd = function(baktun, katun, tun, uinal, kin) {
return this.constants.mayan.COUNT_EPOCH +
(baktun * 144000) +
(katun * 7200) +
(tun * 360) +
(uinal * 20) +
kin;
}```
• Calculate Mayan long count from Julian day

```  calendar.jdToMayanCount = function(jd) {
var d, baktun, katun, tun, uinal, kin;

jd     = Math.floor(jd) + 0.5;
d      = jd - this.constants.mayan.COUNT_EPOCH;
baktun = Math.floor(d / 144000);
d      = astro.mod(d, 144000);
katun  = Math.floor(d / 7200);
d      = astro.mod(d, 7200);
tun    = Math.floor(d / 360);
d      = astro.mod(d, 360);
uinal  = Math.floor(d / 20);
kin    = astro.mod(d, 20);

return [baktun, katun, tun, uinal, kin];
}```
• Determine Mayan Haab "month" and day from Julian day

```  calendar.jdToMayanHaab = function(jd) {
var lcount, day;

jd     = Math.floor(jd) + 0.5;
lcount = jd - this.constants.mayan.COUNT_EPOCH;
day    = astro.mod(lcount + 8 + ((18 - 1) * 20), 365);

return [Math.floor(day / 20) + 1, astro.mod(day, 20)];
}```
• Determine Mayan Tzolkin "month" and day from Julian day

```  calendar.jdToMayanTzolkin = function(jd) {
var lcount;

jd     = Math.floor(jd) + 0.5;
lcount = jd - this.constants.mayan.COUNT_EPOCH;

return [astro.amod(lcount + 20, 20), astro.amod(lcount + 4, 13)];
}```
• Determine Julian day from Bahai date

```  calendar.bahaiToJd = function(major, cycle, year, month, day) {
var gy;

gy = (361 * (major - 1)) + (19 * (cycle - 1)) + (year - 1) +
this.jdToGregorian(this.constants.bahai.EPOCH);
return this.gregorianToJd(gy, 3, 20) + (19 * (month - 1)) +
((month != 20) ? 0 : (this.leapGregorian(gy + 1) ? -14 : -15)) +
day;
}```
• Calculate Bahai date from Julian day

```  calendar.jdToBahai = function(jd) {
var major, cycle, year, month, day,
gy, bstarty, bys, days, bld;

jd      = Math.floor(jd) + 0.5;
gy      = this.jdToGregorian(jd);
bstarty = this.jdToGregorian(this.constants.bahai.EPOCH);
bys     = gy - (bstarty + (((this.gregorianToJd(gy, 1, 1) <= jd) &&
(jd <= this.gregorianToJd(gy, 3, 20))) ? 1 : 0));
major   = Math.floor(bys / 361) + 1;
cycle   = Math.floor(astro.mod(bys, 361) / 19) + 1;
year    = astro.mod(bys, 19) + 1;
days    = jd - this.bahaiToJd(major, cycle, year, 1, 1);
bld     = this.bahaiToJd(major, cycle, year, 20, 1);
month   = (jd >= bld) ? 20 : (Math.floor(days / 19) + 1);
day     = (jd + 1) - this.bahaiToJd(major, cycle, year, month, 1);

return [major, cycle, year, month, day];
}```
• Obtain Julian day for Indian Civil date

```  calendar.indianCivilToJd = function(year, month, day) {
var Caitra, gyear, leap, start, jd, m;

gyear  = year + 78;
leap   = this.leapGregorian(gyear); // Is this a leap year ?
start  = this.gregorianToJd(gyear, 3, leap ? 21 : 22);
Caitra = leap ? 31 : 30;

if (month == 1) {
jd = start + (day - 1);
} else {
jd = start + Caitra;
m = month - 2;
m = Math.min(m, 5);
jd += m * 31;

if (month >= 8) {
m = month - 7;
jd += m * 30;
}

jd += day - 1;
}

return jd;
}```
• Calculate Indian Civil date from Julian day

```  calendar.jdToIndianCivil = function(jd) {
var Caitra, Saka, greg, greg0, leap, start, year, month, day, yday, mday;```
• Offset in years from Saka era to Gregorian epoch

`    Saka  = 79 - 1;`
• Day offset between Saka and Gregorian

```    start = 80;

jd     = Math.floor(jd) + 0.5;
greg   = this.jdToGregorian(jd); // Gregorian date for Julian day
leap   = this.leapGregorian(greg); // Is this a leap year?
year   = greg - Saka; // Tentative year in Saka era
greg0  = this.gregorianToJd(greg, 1, 1); // JD at start of Gregorian year
yday   = jd - greg0; // Day number (0 based) in Gregorian year
Caitra = leap ? 31 : 30; // Days in Caitra this year

if (yday < start) {```
• Day is at the end of the preceding Saka year

```      year--;
yday += Caitra + (31 * 5) + (30 * 3) + 10 + start;
}

yday -= start;

if (yday < Caitra) {
month = 1;
day = yday + 1;
} else {
mday = yday - Caitra;
if (mday < (31 * 5)) {
month = Math.floor(mday / 31) + 2;
day = (mday % 31) + 1;
} else {
mday -= 31 * 5;
month = Math.floor(mday / 30) + 7;
day = (mday % 30) + 1;
}
}

return [year, month, day];
}

return exports;
}(Calendrical || {}));```