-
Notifications
You must be signed in to change notification settings - Fork 5
/
calendar.js
120 lines (96 loc) · 3.03 KB
/
calendar.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
JavaScript functions for the Fourmilab Calendar Converter
by John Walker -- September, MIM
http://www.fourmilab.ch/documents/calendar/
This program is in the public domain.
*/
/* MOD -- Modulus function which works for non-integers. */
function mod(a, b) {
return a - (b * Math.floor(a / b));
}
// LEAP_GREGORIAN -- Is a given year in the Gregorian calendar a leap year ?
function leap_gregorian(year) {
return ((year % 4) == 0) &&
(!(((year % 100) == 0) && ((year % 400) != 0)));
}
// GREGORIAN_TO_JD -- Determine Julian day number from Gregorian calendar date
var GREGORIAN_EPOCH = 1721425.5;
function gregorian_to_jd(year, month, day) {
return (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 :
(leap_gregorian(year) ? -1 : -2)
) +
day);
}
// JD_TO_GREGORIAN -- Calculate Gregorian calendar date from Julian day
function jd_to_gregorian(jd) {
var wjd, depoch, quadricent, dqc, cent, dcent, quad, dquad,
yindex, year, yearday, leapadj;
wjd = Math.floor(jd - 0.5) + 0.5;
depoch = wjd - GREGORIAN_EPOCH;
quadricent = Math.floor(depoch / 146097);
dqc = mod(depoch, 146097);
cent = Math.floor(dqc / 36524);
dcent = mod(dqc, 36524);
quad = Math.floor(dcent / 1461);
dquad = mod(dcent, 1461);
yindex = Math.floor(dquad / 365);
year = (quadricent * 400) + (cent * 100) + (quad * 4) + yindex;
if (!((cent == 4) || (yindex == 4))) {
year++;
}
yearday = wjd - gregorian_to_jd(year, 1, 1);
leapadj = ((wjd < gregorian_to_jd(year, 3, 1)) ? 0
:
(leap_gregorian(year) ? 1 : 2)
);
var month = Math.floor((((yearday + leapadj) * 12) + 373) / 367),
day = (wjd - gregorian_to_jd(year, month, 1)) + 1;
return [year, month, day];
}
var PERSIAN_EPOCH = 1948320.5;
// PERSIAN_TO_JD -- Determine Julian day from Persian date
function persian_to_jd(year, month, day) {
var epbase, epyear;
epbase = year - ((year >= 0) ? 474 : 473);
epyear = 474 + 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 +
(PERSIAN_EPOCH - 1);
}
// JD_TO_PERSIAN -- Calculate Persian date from Julian day
function jd_to_persian(jd) {
var year, month, day, depoch, cycle, cyear, ycycle,
aux1, aux2, yday;
jd = Math.floor(jd) + 0.5;
depoch = jd - persian_to_jd(475, 1, 1);
cycle = Math.floor(depoch / 1029983);
cyear = mod(depoch, 1029983);
if (cyear == 1029982) {
ycycle = 2820;
} else {
aux1 = Math.floor(cyear / 366);
aux2 = 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 - persian_to_jd(year, 1, 1)) + 1;
month = (yday <= 186) ? Math.ceil(yday / 31) : Math.ceil((yday - 6) / 30);
day = (jd - persian_to_jd(year, month, 1)) + 1;
return [year, month, day];
}