3 var ABOUT = "\u00C2m l\u1ECBch Vi\u1EC7t Nam - Version 0.8"+"\n\u00A9 2004 H\u1ED3 Ng\u1ECDc \u0110\u1EE9c [http://come.to/duc]";
\r
4 var TK19 = new Array(
\r
5 0x30baa3, 0x56ab50, 0x422ba0, 0x2cab61, 0x52a370, 0x3c51e8, 0x60d160, 0x4ae4b0, 0x376926, 0x58daa0,
\r
6 0x445b50, 0x3116d2, 0x562ae0, 0x3ea2e0, 0x28e2d2, 0x4ec950, 0x38d556, 0x5cb520, 0x46b690, 0x325da4,
\r
7 0x5855d0, 0x4225d0, 0x2ca5b3, 0x52a2b0, 0x3da8b7, 0x60a950, 0x4ab4a0, 0x35b2a5, 0x5aad50, 0x4455b0,
\r
8 0x302b74, 0x562570, 0x4052f9, 0x6452b0, 0x4e6950, 0x386d56, 0x5e5aa0, 0x46ab50, 0x3256d4, 0x584ae0,
\r
9 0x42a570, 0x2d4553, 0x50d2a0, 0x3be8a7, 0x60d550, 0x4a5aa0, 0x34ada5, 0x5a95d0, 0x464ae0, 0x2eaab4,
\r
10 0x54a4d0, 0x3ed2b8, 0x64b290, 0x4cb550, 0x385757, 0x5e2da0, 0x4895d0, 0x324d75, 0x5849b0, 0x42a4b0,
\r
11 0x2da4b3, 0x506a90, 0x3aad98, 0x606b50, 0x4c2b60, 0x359365, 0x5a9370, 0x464970, 0x306964, 0x52e4a0,
\r
12 0x3cea6a, 0x62da90, 0x4e5ad0, 0x392ad6, 0x5e2ae0, 0x4892e0, 0x32cad5, 0x56c950, 0x40d4a0, 0x2bd4a3,
\r
13 0x50b690, 0x3a57a7, 0x6055b0, 0x4c25d0, 0x3695b5, 0x5a92b0, 0x44a950, 0x2ed954, 0x54b4a0, 0x3cb550,
\r
14 0x286b52, 0x4e55b0, 0x3a2776, 0x5e2570, 0x4852b0, 0x32aaa5, 0x56e950, 0x406aa0, 0x2abaa3, 0x50ab50
\r
15 ); /* Years 2000-2099 */
\r
17 var TK20 = new Array(
\r
18 0x3c4bd8, 0x624ae0, 0x4ca570, 0x3854d5, 0x5cd260, 0x44d950, 0x315554, 0x5656a0, 0x409ad0, 0x2a55d2,
\r
19 0x504ae0, 0x3aa5b6, 0x60a4d0, 0x48d250, 0x33d255, 0x58b540, 0x42d6a0, 0x2cada2, 0x5295b0, 0x3f4977,
\r
20 0x644970, 0x4ca4b0, 0x36b4b5, 0x5c6a50, 0x466d50, 0x312b54, 0x562b60, 0x409570, 0x2c52f2, 0x504970,
\r
21 0x3a6566, 0x5ed4a0, 0x48ea50, 0x336a95, 0x585ad0, 0x442b60, 0x2f86e3, 0x5292e0, 0x3dc8d7, 0x62c950,
\r
22 0x4cd4a0, 0x35d8a6, 0x5ab550, 0x4656a0, 0x31a5b4, 0x5625d0, 0x4092d0, 0x2ad2b2, 0x50a950, 0x38b557,
\r
23 0x5e6ca0, 0x48b550, 0x355355, 0x584da0, 0x42a5b0, 0x2f4573, 0x5452b0, 0x3ca9a8, 0x60e950, 0x4c6aa0,
\r
24 0x36aea6, 0x5aab50, 0x464b60, 0x30aae4, 0x56a570, 0x405260, 0x28f263, 0x4ed940, 0x38db47, 0x5cd6a0,
\r
25 0x4896d0, 0x344dd5, 0x5a4ad0, 0x42a4d0, 0x2cd4b4, 0x52b250, 0x3cd558, 0x60b540, 0x4ab5a0, 0x3755a6,
\r
26 0x5c95b0, 0x4649b0, 0x30a974, 0x56a4b0, 0x40aa50, 0x29aa52, 0x4e6d20, 0x39ad47, 0x5eab60, 0x489370,
\r
27 0x344af5, 0x5a4970, 0x4464b0, 0x2c74a3, 0x50ea50, 0x3d6a58, 0x6256a0, 0x4aaad0, 0x3696d5, 0x5c92e0
\r
28 ); /* Years 1900-1999 */
\r
30 var TK21 = new Array(
\r
31 0x46c960, 0x2ed954, 0x54d4a0, 0x3eda50, 0x2a7552, 0x4e56a0, 0x38a7a7, 0x5ea5d0, 0x4a92b0, 0x32aab5,
\r
32 0x58a950, 0x42b4a0, 0x2cbaa4, 0x50ad50, 0x3c55d9, 0x624ba0, 0x4ca5b0, 0x375176, 0x5c5270, 0x466930,
\r
33 0x307934, 0x546aa0, 0x3ead50, 0x2a5b52, 0x504b60, 0x38a6e6, 0x5ea4e0, 0x48d260, 0x32ea65, 0x56d520,
\r
34 0x40daa0, 0x2d56a3, 0x5256d0, 0x3c4afb, 0x6249d0, 0x4ca4d0, 0x37d0b6, 0x5ab250, 0x44b520, 0x2edd25,
\r
35 0x54b5a0, 0x3e55d0, 0x2a55b2, 0x5049b0, 0x3aa577, 0x5ea4b0, 0x48aa50, 0x33b255, 0x586d20, 0x40ad60,
\r
36 0x2d4b63, 0x525370, 0x3e49e8, 0x60c970, 0x4c54b0, 0x3768a6, 0x5ada50, 0x445aa0, 0x2fa6a4, 0x54aad0,
\r
37 0x4052e0, 0x28d2e3, 0x4ec950, 0x38d557, 0x5ed4a0, 0x46d950, 0x325d55, 0x5856a0, 0x42a6d0, 0x2c55d4,
\r
38 0x5252b0, 0x3ca9b8, 0x62a930, 0x4ab490, 0x34b6a6, 0x5aad50, 0x4655a0, 0x2eab64, 0x54a570, 0x4052b0,
\r
39 0x2ab173, 0x4e6930, 0x386b37, 0x5e6aa0, 0x48ad50, 0x332ad5, 0x582b60, 0x42a570, 0x2e52e4, 0x50d160,
\r
40 0x3ae958, 0x60d520, 0x4ada90, 0x355aa6, 0x5a56d0, 0x462ae0, 0x30a9d4, 0x54a2d0, 0x3ed150, 0x28e952
\r
41 ); /* Years 2000-2099 */
\r
43 var TK22 = new Array(
\r
44 0x4eb520, 0x38d727, 0x5eada0, 0x4a55b0, 0x362db5, 0x5a45b0, 0x44a2b0, 0x2eb2b4, 0x54a950, 0x3cb559,
\r
45 0x626b20, 0x4cad50, 0x385766, 0x5c5370, 0x484570, 0x326574, 0x5852b0, 0x406950, 0x2a7953, 0x505aa0,
\r
46 0x3baaa7, 0x5ea6d0, 0x4a4ae0, 0x35a2e5, 0x5aa550, 0x42d2a0, 0x2de2a4, 0x52d550, 0x3e5abb, 0x6256a0,
\r
47 0x4c96d0, 0x3949b6, 0x5e4ab0, 0x46a8d0, 0x30d4b5, 0x56b290, 0x40b550, 0x2a6d52, 0x504da0, 0x3b9567,
\r
48 0x609570, 0x4a49b0, 0x34a975, 0x5a64b0, 0x446a90, 0x2cba94, 0x526b50, 0x3e2b60, 0x28ab61, 0x4c9570,
\r
49 0x384ae6, 0x5cd160, 0x46e4a0, 0x2eed25, 0x54da90, 0x405b50, 0x2c36d3, 0x502ae0, 0x3a93d7, 0x6092d0,
\r
50 0x4ac950, 0x32d556, 0x58b4a0, 0x42b690, 0x2e5d94, 0x5255b0, 0x3e25fa, 0x6425b0, 0x4e92b0, 0x36aab6,
\r
51 0x5c6950, 0x4674a0, 0x31b2a5, 0x54ad50, 0x4055a0, 0x2aab73, 0x522570, 0x3a5377, 0x6052b0, 0x4a6950,
\r
52 0x346d56, 0x585aa0, 0x42ab50, 0x2e56d4, 0x544ae0, 0x3ca570, 0x2864d2, 0x4cd260, 0x36eaa6, 0x5ad550,
\r
53 0x465aa0, 0x30ada5, 0x5695d0, 0x404ad0, 0x2aa9b3, 0x50a4d0, 0x3ad2b7, 0x5eb250, 0x48b540, 0x33d556
\r
54 ); /* Years 2100-2199 */
\r
56 var CAN = new Array("Gi\341p", "\u1EA4t", "B\355nh", "\u0110inh", "M\u1EADu", "K\u1EF7", "Canh", "T\342n", "Nh\342m", "Qu\375");
\r
57 var CHI = new Array("T\375", "S\u1EEDu", "D\u1EA7n", "Mão", "Th\354n", "T\u1EF5", "Ng\u1ECD", "M\371i", "Th\342n", "D\u1EADu", "Tu\u1EA5t", "H\u1EE3i");
\r
58 var TUAN = new Array("Ch\u1EE7 Nh\u1EADt", "Th\u1EE9 Hai", "Th\u1EE9 Ba", "Th\u1EE9 T\u01B0", "Th\u1EE9 N\u0103m", "Th\u1EE9 S\341u", "Th\u1EE9 B\u1EA3y");
\r
59 var GIO_HD = new Array("110100101100", "001101001011", "110011010010", "101100110100", "001011001101", "010010110011");
\r
60 var TIETKHI = new Array("Xu\u00E2n ph\u00E2n", "Thanh minh", "C\u1ED1c v\u0169", "L\u1EADp h\u1EA1", "Ti\u1EC3u m\u00E3n", "Mang ch\u1EE7ng",
\r
61 "H\u1EA1 ch\u00ED", "Ti\u1EC3u th\u1EED", "\u0110\u1EA1i th\u1EED", "L\u1EADp thu", "X\u1EED th\u1EED", "B\u1EA1ch l\u1ED9",
\r
62 "Thu ph\u00E2n", "H\u00E0n l\u1ED9", "S\u01B0\u01A1ng gi\u00E1ng", "L\u1EADp \u0111\u00F4ng", "Ti\u1EC3u tuy\u1EBFt", "\u0110\u1EA1i tuy\u1EBFt",
\r
63 "\u0110\u00F4ng ch\u00ED", "Ti\u1EC3u h\u00E0n", "\u0110\u1EA1i h\u00E0n", "L\u1EADp xu\u00E2n", "V\u0169 Th\u1EE7y", "Kinh tr\u1EADp"
\r
68 /* Create lunar date object, stores (lunar) date, month, year, leap month indicator, and Julian date number */
\r
69 function LunarDate(dd, mm, yy, leap, jd) {
\r
79 /* Discard the fractional part of a number, e.g., INT(3.2) = 3 */
\r
81 return Math.floor(d);
\r
84 function jdn(dd, mm, yy) {
\r
85 var a = INT((14 - mm) / 12);
\r
88 var jd = dd + INT((153*m+2)/5) + 365*y + INT(y/4) - INT(y/100) + INT(y/400) - 32045;
\r
90 //return 367*yy - INT(7*(yy+INT((mm+9)/12))/4) - INT(3*(INT((yy+(mm-9)/7)/100)+1)/4) + INT(275*mm/9)+dd+1721029;
\r
93 function jdn2date(jd) {
\r
94 var Z, A, alpha, B, C, D, E, dd, mm, yyyy, F;
\r
99 alpha = INT((Z-1867216.25)/36524.25);
\r
100 A = Z + 1 + alpha - INT(alpha/4);
\r
103 C = INT( (B-122.1)/365.25);
\r
104 D = INT( 365.25*C );
\r
105 E = INT( (B-D)/30.6001 );
\r
106 dd = INT(B - D - INT(30.6001*E));
\r
117 return new Array(dd, mm, yyyy);
\r
120 function decodeLunarYear(yy, k) {
\r
121 var monthLengths, regularMonths, offsetOfTet, leapMonth, leapMonthLength, solarNY, currentJD, j, mm;
\r
122 var ly = new Array();
\r
123 monthLengths = new Array(29, 30);
\r
124 var regularMonths = new Array(12);
\r
125 offsetOfTet = k >> 17;
\r
126 leapMonth = k & 0xf;
\r
127 leapMonthLength = monthLengths[k >> 16 & 0x1];
\r
128 solarNY = jdn(1, 1, yy);
\r
129 currentJD = solarNY+offsetOfTet;
\r
131 for(var i = 0; i < 12; i++) {
\r
132 regularMonths[12 - i - 1] = monthLengths[j & 0x1];
\r
135 if (leapMonth == 0) {
\r
136 for(mm = 1; mm <= 12; mm++) {
\r
137 ly.push(new LunarDate(1, mm, yy, 0, currentJD));
\r
138 currentJD += regularMonths[mm-1];
\r
141 for(mm = 1; mm <= leapMonth; mm++) {
\r
142 ly.push(new LunarDate(1, mm, yy, 0, currentJD));
\r
143 currentJD += regularMonths[mm-1];
\r
145 ly.push(new LunarDate(1, leapMonth, yy, 1, currentJD));
\r
146 currentJD += leapMonthLength;
\r
147 for(mm = leapMonth+1; mm <= 12; mm++) {
\r
148 ly.push(new LunarDate(1, mm, yy, 0, currentJD));
\r
149 currentJD += regularMonths[mm-1];
\r
153 LML = leapMonthLength;
\r
154 RMM = regularMonths;
\r
158 function leapMonth(yyyy){
\r
159 var yearCode = getYearCode(yyyy);
\r
160 return yearCode & 0xf;
\r
163 function monthLength(yyyy){
\r
164 var yearCode = getYearCode(yyyy);
\r
165 return yearCode >> 16 & 0x1;
\r
168 function getYearCode(yyyy){
\r
171 yearCode = TK19[yyyy - 1800];
\r
172 } else if (yyyy < 2000) {
\r
173 yearCode = TK20[yyyy - 1900];
\r
174 } else if (yyyy < 2100) {
\r
175 yearCode = TK21[yyyy - 2000];
\r
177 yearCode = TK22[yyyy - 2100];
\r
182 function getYearInfo(yyyy) {
\r
185 yearCode = TK19[yyyy - 1800];
\r
186 } else if (yyyy < 2000) {
\r
187 yearCode = TK20[yyyy - 1900];
\r
188 } else if (yyyy < 2100) {
\r
189 yearCode = TK21[yyyy - 2000];
\r
191 yearCode = TK22[yyyy - 2100];
\r
193 return decodeLunarYear(yyyy, yearCode);
\r
196 var FIRST_DAY = jdn(25, 1, 1800); // Tet am lich 1800
\r
197 var LAST_DAY = jdn(31, 12, 2199);
\r
199 function findLunarDate(jd, ly) {
\r
200 if (jd > LAST_DAY || jd < FIRST_DAY || ly[0].jd > jd) {
\r
201 return new LunarDate(0, 0, 0, 0, jd);
\r
203 var i = ly.length-1;
\r
204 while (jd < ly[i].jd) {
\r
207 var off = jd - ly[i].jd;
\r
208 var ret = new LunarDate(ly[i].day+off, ly[i].month, ly[i].year, ly[i].leap, jd);
\r
212 function getLunarDate(dd, mm, yyyy) {
\r
214 if (yyyy < 1800 || 2199 < yyyy) {
\r
215 //return new LunarDate(0, 0, 0, 0, 0);
\r
217 ly = getYearInfo(yyyy);
\r
218 jd = jdn(dd, mm, yyyy);
\r
219 if (jd < ly[0].jd) {
\r
220 ly = getYearInfo(yyyy - 1);
\r
222 return findLunarDate(jd, ly);
\r
225 /* Compute the longitude of the sun at any time.
\r
226 * Parameter: floating number jdn, the number of days since 1/1/4713 BC noon
\r
227 * Algorithm from: "Astronomical Algorithms" by Jean Meeus, 1998
\r
229 function SunLongitude(jdn) {
\r
230 var T, T2, dr, M, L0, DL, lambda, theta, omega;
\r
231 T = (jdn - 2451545.0 ) / 36525; // Time in Julian centuries from 2000-01-01 12:00:00 GMT
\r
233 dr = PI/180; // degree to radian
\r
234 M = 357.52910 + 35999.05030*T - 0.0001559*T2 - 0.00000048*T*T2; // mean anomaly, degree
\r
235 L0 = 280.46645 + 36000.76983*T + 0.0003032*T2; // mean longitude, degree
\r
236 DL = (1.914600 - 0.004817*T - 0.000014*T2)*Math.sin(dr*M);
\r
237 DL = DL + (0.019993 - 0.000101*T)*Math.sin(dr*2*M) + 0.000290*Math.sin(dr*3*M);
\r
238 theta = L0 + DL; // true longitude, degree
\r
239 // obtain apparent longitude by correcting for nutation and aberration
\r
240 omega = 125.04 - 1934.136 * T;
\r
241 lambda = theta - 0.00569 - 0.00478 * Math.sin(omega * dr);
\r
242 // Convert to radians
\r
243 lambda = lambda*dr;
\r
244 lambda = lambda - PI*2*(INT(lambda/(PI*2))); // Normalize to (0, 2*PI)
\r
248 /* Compute the sun segment at start (00:00) of the day with the given integral Julian day number.
\r
249 * The time zone if the time difference between local time and UTC: 7.0 for UTC+7:00.
\r
250 * The function returns a number between 0 and 23.
\r
251 * From the day after March equinox and the 1st major term after March equinox, 0 is returned.
\r
252 * After that, return 1, 2, 3 ...
\r
254 function getSunLongitude(dayNumber, timeZone) {
\r
255 return INT(SunLongitude(dayNumber - 0.5 - timeZone/24.0) / PI * 12);
\r
258 var today = new Date();
\r
259 //var currentLunarYear = getYearInfo(today.getFullYear());
\r
260 var currentLunarDate = getLunarDate(today.getDate(), today.getMonth()+1, today.getFullYear());
\r
261 var currentMonth = today.getMonth()+1;
\r
262 var currentYear = today.getFullYear();
\r
264 function parseQuery(q) {
\r
265 var ret = new Array();
\r
266 if (q.length < 2) return ret;
\r
267 var s = q.substring(1, q.length);
\r
268 var arr = s.split("&");
\r
270 for (i = 0; i < arr.length; i++) {
\r
271 var a = arr[i].split("=");
\r
272 for (j = 0; j < a.length; j++) {
\r
279 function getSelectedMonth() {
\r
280 var query = window.location.search;
\r
281 var arr = parseQuery(query);
\r
283 for (idx = 0; idx < arr.length; idx++) {
\r
284 if (arr[idx] == "mm") {
\r
285 currentMonth = parseInt(arr[idx+1]);
\r
286 } else if (arr[idx] == "yy") {
\r
287 currentYear = parseInt(arr[idx+1]);
\r
292 function getMonth(mm, yy) {
\r
293 var ly1, ly2, tet1, jd1, jd2, mm1, yy1, result, i;
\r
301 jd1 = jdn(1, mm, yy);
\r
302 jd2 = jdn(1, mm1, yy1);
\r
303 ly1 = getYearInfo(yy);
\r
304 //alert('1/'+mm+'/'+yy+' = '+jd1+'; 1/'+mm1+'/'+yy1+' = '+jd2);
\r
306 result = new Array();
\r
307 if (tet1 <= jd1) { /* tet(yy) = tet1 < jd1 < jd2 <= 1.1.(yy+1) < tet(yy+1) */
\r
308 for (i = jd1; i < jd2; i++) {
\r
309 result.push(findLunarDate(i, ly1));
\r
311 } else if (jd1 < tet1 && jd2 < tet1) { /* tet(yy-1) < jd1 < jd2 < tet1 = tet(yy) */
\r
312 ly1 = getYearInfo(yy - 1);
\r
313 for (i = jd1; i < jd2; i++) {
\r
314 result.push(findLunarDate(i, ly1));
\r
316 } else if (jd1 < tet1 && tet1 <= jd2) { /* tet(yy-1) < jd1 < tet1 <= jd2 < tet(yy+1) */
\r
317 ly2 = getYearInfo(yy - 1);
\r
318 for (i = jd1; i < tet1; i++) {
\r
319 result.push(findLunarDate(i, ly2));
\r
321 for (i = tet1; i < jd2; i++) {
\r
322 result.push(findLunarDate(i, ly1));
\r
328 function getDayName(lunarDate) {
\r
329 if (lunarDate.day == 0) {
\r
332 var cc = getCanChi(lunarDate);
\r
333 var s = "Ng\u00E0y " + cc[0] +", th\341ng "+cc[1] + ", n\u0103m " + cc[2];
\r
337 function getYearCanChi(year) {
\r
338 return CAN[(year+6) % 10] + " " + CHI[(year+8) % 12];
\r
342 * Can cua gio Chinh Ty (00:00) cua ngay voi JDN nay
\r
344 function getCanHour0(jdn) {
\r
345 return CAN[(jdn-1)*2 % 10];
\r
348 function getCanChi(lunar) {
\r
349 var dayName, monthName, yearName;
\r
350 dayName = CAN[(lunar.jd + 9) % 10] + " " + CHI[(lunar.jd+1)%12];
\r
351 monthName = CAN[(lunar.year*12+lunar.month+3) % 10] + " " + CHI[(lunar.month+1)%12];
\r
352 if (lunar.leap == 1) {
\r
353 monthName += " (N)";
\r
355 yearName = getYearCanChi(lunar.year);
\r
356 return new Array(dayName, monthName, yearName);
\r
359 function getDayString(lunar, solarDay, solarMonth, solarYear) {
\r
361 var dayOfWeek = TUAN[(lunar.jd + 1) % 7];
\r
362 s = dayOfWeek + " " + solarDay + "/" + solarMonth + "/" + solarYear;
\r
364 s = s + "Ng\u00E0y " + lunar.day+" th\341ng "+lunar.month;
\r
365 if (lunar.leap == 1) {
\r
366 s = s + " nhu\u1EADn";
\r
371 function getTodayString() {
\r
372 var s = getDayString(currentLunarDate, today.getDate(), today.getMonth()+1, today.getFullYear());
\r
373 s += " n\u0103m " + getYearCanChi(currentLunarDate.year);
\r
377 function getCurrentTime() {
\r
378 today = new Date();
\r
379 var Std = today.getHours();
\r
380 var Min = today.getMinutes();
\r
381 var Sec = today.getSeconds();
\r
382 var s1 = ((Std < 10) ? "0" + Std : Std);
\r
383 var s2 = ((Min < 10) ? "0" + Min : Min);
\r
384 //var s3 = ((Sec < 10) ? "0" + Sec : Sec);
\r
385 //return s1 + ":" + s2 + ":" + s3;
\r
386 return s1 + ":" + s2;
\r
389 function getGioHoangDao(jd) {
\r
390 var chiOfDay = (jd+1) % 12;
\r
391 var gioHD = GIO_HD[chiOfDay % 6]; // same values for Ty' (1) and Ngo. (6), for Suu and Mui etc.
\r
394 for (var i = 0; i < 12; i++) {
\r
395 if (gioHD.charAt(i) == '1') {
\r
397 ret += ' ('+(i*2+23)%24+'h-'+(i*2+1)%24+'h)';
\r
398 if (count++ < 5) ret += ', ';
\r
399 if (count == 3) ret += '<br>';
\r
405 function getTHU(jd){
\r
406 return TUAN[(jd+1)%7];
\r
409 function getTHUINT(jd){
\r