f380b6f7e4c7818de54c8a8108049d163b9f1ace
[lichviet-widget] / qml / lichvietwidget / main.js
1 /*
2 Copyright (C) 2011  by Cuong Le <metacuong@gmail.com>
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>
16 */
17
18 var IMGS_RESOURCE_PATH = "/opt/lichvietwidget/qml/lichvietwidget/imgs/";
19 var isday=-1;
20 var ismonth=-1;
21 var isyear=-1;
22
23 function refresh(day_center_img, day_left_img, day_right_img, month_left_img, month_right_img, year_1_img, year_2_img,year_3_img,year_4_img, txt_detail) {
24     var date = new Date();
25
26     var lunar = getLunarDate(date.getDate(),date.getMonth()+1,date.getFullYear());
27     var lunarCanChi = getCanChi(lunar);
28     var xday = lunar.day;
29     var xmonth = lunar.month;
30     var xyear = lunar.year;
31
32     txt_detail.text = "Ngày <b>"+lunarCanChi[0]+"</b>, Tháng <b>"+lunarCanChi[1]+"</b><br>Năm <b>"+lunarCanChi[2]+"</b>";
33
34     if (xday != isday){
35         if (xday <= 9){
36             day_center_img.visible = true;
37             day_center_img.source = IMGS_RESOURCE_PATH + xday + ".png";
38             day_left_img.visible = false;
39             day_right_img.visible = false;
40         }else{
41             var strxday = xday+'';
42             var firstday = strxday[0];
43             var secondday = strxday[1];
44             day_center_img.visible = false;
45             day_left_img.visible = true;
46             day_left_img.source = IMGS_RESOURCE_PATH + firstday + ".png";
47             day_right_img.visible = true;
48             day_right_img.source = IMGS_RESOURCE_PATH + secondday + ".png";
49         }
50         isday = xday;
51     }
52
53     if (xmonth != ismonth){
54         if (xmonth <=9){
55             month_left_img.source = IMGS_RESOURCE_PATH +"0.png";
56             month_right_img.source = IMGS_RESOURCE_PATH + xmonth + ".png";
57         }else
58         {
59             var strxmonth = xmonth+'';
60             var firstmonth = strxmonth[0];
61             var secondmonth = strxmonth[1];
62             month_left_img.source = IMGS_RESOURCE_PATH + firstmonth +".png";
63             month_right_img.source = IMGS_RESOURCE_PATH + secondmonth + ".png";
64         }
65         ismonth=xmonth;
66     }
67
68     if (xyear != isyear){
69         var strxyear = xyear+'';
70         year_1_img.source = IMGS_RESOURCE_PATH + strxyear[0] +".png";
71         year_2_img.source = IMGS_RESOURCE_PATH + strxyear[1] + ".png";
72         year_3_img.source = IMGS_RESOURCE_PATH + strxyear[2] +".png";
73         year_4_img.source = IMGS_RESOURCE_PATH + strxyear[3] + ".png";
74         isyear=xyear;
75     }
76 }
77
78 /**
79  * Copyright 2004 Ho Ngoc Duc [http://come.to/duc]. All Rights Reserved.<p>
80  * Permission to use, copy, modify, and redistribute this software and its
81  * documentation for personal, non-commercial use is hereby granted provided that
82  * this copyright notice appears in all copies.
83  */
84
85 var ABOUT = "\u00C2m l\u1ECBch Vi\u1EC7t Nam - Version 0.8"+"\n\u00A9 2004 H\u1ED3 Ng\u1ECDc \u0110\u1EE9c [http://come.to/duc]";
86 var TK19 = new Array(
87         0x30baa3, 0x56ab50, 0x422ba0, 0x2cab61, 0x52a370, 0x3c51e8, 0x60d160, 0x4ae4b0, 0x376926, 0x58daa0,
88         0x445b50, 0x3116d2, 0x562ae0, 0x3ea2e0, 0x28e2d2, 0x4ec950, 0x38d556, 0x5cb520, 0x46b690, 0x325da4,
89         0x5855d0, 0x4225d0, 0x2ca5b3, 0x52a2b0, 0x3da8b7, 0x60a950, 0x4ab4a0, 0x35b2a5, 0x5aad50, 0x4455b0,
90         0x302b74, 0x562570, 0x4052f9, 0x6452b0, 0x4e6950, 0x386d56, 0x5e5aa0, 0x46ab50, 0x3256d4, 0x584ae0,
91         0x42a570, 0x2d4553, 0x50d2a0, 0x3be8a7, 0x60d550, 0x4a5aa0, 0x34ada5, 0x5a95d0, 0x464ae0, 0x2eaab4,
92         0x54a4d0, 0x3ed2b8, 0x64b290, 0x4cb550, 0x385757, 0x5e2da0, 0x4895d0, 0x324d75, 0x5849b0, 0x42a4b0,
93         0x2da4b3, 0x506a90, 0x3aad98, 0x606b50, 0x4c2b60, 0x359365, 0x5a9370, 0x464970, 0x306964, 0x52e4a0,
94         0x3cea6a, 0x62da90, 0x4e5ad0, 0x392ad6, 0x5e2ae0, 0x4892e0, 0x32cad5, 0x56c950, 0x40d4a0, 0x2bd4a3,
95         0x50b690, 0x3a57a7, 0x6055b0, 0x4c25d0, 0x3695b5, 0x5a92b0, 0x44a950, 0x2ed954, 0x54b4a0, 0x3cb550,
96         0x286b52, 0x4e55b0, 0x3a2776, 0x5e2570, 0x4852b0, 0x32aaa5, 0x56e950, 0x406aa0, 0x2abaa3, 0x50ab50
97 ); /* Years 2000-2099 */
98
99 var TK20 = new Array(
100         0x3c4bd8, 0x624ae0, 0x4ca570, 0x3854d5, 0x5cd260, 0x44d950, 0x315554, 0x5656a0, 0x409ad0, 0x2a55d2,
101         0x504ae0, 0x3aa5b6, 0x60a4d0, 0x48d250, 0x33d255, 0x58b540, 0x42d6a0, 0x2cada2, 0x5295b0, 0x3f4977,
102         0x644970, 0x4ca4b0, 0x36b4b5, 0x5c6a50, 0x466d50, 0x312b54, 0x562b60, 0x409570, 0x2c52f2, 0x504970,
103         0x3a6566, 0x5ed4a0, 0x48ea50, 0x336a95, 0x585ad0, 0x442b60, 0x2f86e3, 0x5292e0, 0x3dc8d7, 0x62c950,
104         0x4cd4a0, 0x35d8a6, 0x5ab550, 0x4656a0, 0x31a5b4, 0x5625d0, 0x4092d0, 0x2ad2b2, 0x50a950, 0x38b557,
105         0x5e6ca0, 0x48b550, 0x355355, 0x584da0, 0x42a5b0, 0x2f4573, 0x5452b0, 0x3ca9a8, 0x60e950, 0x4c6aa0,
106         0x36aea6, 0x5aab50, 0x464b60, 0x30aae4, 0x56a570, 0x405260, 0x28f263, 0x4ed940, 0x38db47, 0x5cd6a0,
107         0x4896d0, 0x344dd5, 0x5a4ad0, 0x42a4d0, 0x2cd4b4, 0x52b250, 0x3cd558, 0x60b540, 0x4ab5a0, 0x3755a6,
108         0x5c95b0, 0x4649b0, 0x30a974, 0x56a4b0, 0x40aa50, 0x29aa52, 0x4e6d20, 0x39ad47, 0x5eab60, 0x489370,
109         0x344af5, 0x5a4970, 0x4464b0, 0x2c74a3, 0x50ea50, 0x3d6a58, 0x6256a0, 0x4aaad0, 0x3696d5, 0x5c92e0
110 ); /* Years 1900-1999 */
111
112 var TK21 = new Array(
113         0x46c960, 0x2ed954, 0x54d4a0, 0x3eda50, 0x2a7552, 0x4e56a0, 0x38a7a7, 0x5ea5d0, 0x4a92b0, 0x32aab5,
114         0x58a950, 0x42b4a0, 0x2cbaa4, 0x50ad50, 0x3c55d9, 0x624ba0, 0x4ca5b0, 0x375176, 0x5c5270, 0x466930,
115         0x307934, 0x546aa0, 0x3ead50, 0x2a5b52, 0x504b60, 0x38a6e6, 0x5ea4e0, 0x48d260, 0x32ea65, 0x56d520,
116         0x40daa0, 0x2d56a3, 0x5256d0, 0x3c4afb, 0x6249d0, 0x4ca4d0, 0x37d0b6, 0x5ab250, 0x44b520, 0x2edd25,
117         0x54b5a0, 0x3e55d0, 0x2a55b2, 0x5049b0, 0x3aa577, 0x5ea4b0, 0x48aa50, 0x33b255, 0x586d20, 0x40ad60,
118         0x2d4b63, 0x525370, 0x3e49e8, 0x60c970, 0x4c54b0, 0x3768a6, 0x5ada50, 0x445aa0, 0x2fa6a4, 0x54aad0,
119         0x4052e0, 0x28d2e3, 0x4ec950, 0x38d557, 0x5ed4a0, 0x46d950, 0x325d55, 0x5856a0, 0x42a6d0, 0x2c55d4,
120         0x5252b0, 0x3ca9b8, 0x62a930, 0x4ab490, 0x34b6a6, 0x5aad50, 0x4655a0, 0x2eab64, 0x54a570, 0x4052b0,
121         0x2ab173, 0x4e6930, 0x386b37, 0x5e6aa0, 0x48ad50, 0x332ad5, 0x582b60, 0x42a570, 0x2e52e4, 0x50d160,
122         0x3ae958, 0x60d520, 0x4ada90, 0x355aa6, 0x5a56d0, 0x462ae0, 0x30a9d4, 0x54a2d0, 0x3ed150, 0x28e952
123 ); /* Years 2000-2099 */
124
125 var TK22 = new Array(
126                 0x4eb520, 0x38d727, 0x5eada0, 0x4a55b0, 0x362db5, 0x5a45b0, 0x44a2b0, 0x2eb2b4, 0x54a950, 0x3cb559,
127                 0x626b20, 0x4cad50, 0x385766, 0x5c5370, 0x484570, 0x326574, 0x5852b0, 0x406950, 0x2a7953, 0x505aa0,
128                 0x3baaa7, 0x5ea6d0, 0x4a4ae0, 0x35a2e5, 0x5aa550, 0x42d2a0, 0x2de2a4, 0x52d550, 0x3e5abb, 0x6256a0,
129                 0x4c96d0, 0x3949b6, 0x5e4ab0, 0x46a8d0, 0x30d4b5, 0x56b290, 0x40b550, 0x2a6d52, 0x504da0, 0x3b9567,
130                 0x609570, 0x4a49b0, 0x34a975, 0x5a64b0, 0x446a90, 0x2cba94, 0x526b50, 0x3e2b60, 0x28ab61, 0x4c9570,
131                 0x384ae6, 0x5cd160, 0x46e4a0, 0x2eed25, 0x54da90, 0x405b50, 0x2c36d3, 0x502ae0, 0x3a93d7, 0x6092d0,
132                 0x4ac950, 0x32d556, 0x58b4a0, 0x42b690, 0x2e5d94, 0x5255b0, 0x3e25fa, 0x6425b0, 0x4e92b0, 0x36aab6,
133                 0x5c6950, 0x4674a0, 0x31b2a5, 0x54ad50, 0x4055a0, 0x2aab73, 0x522570, 0x3a5377, 0x6052b0, 0x4a6950,
134                 0x346d56, 0x585aa0, 0x42ab50, 0x2e56d4, 0x544ae0, 0x3ca570, 0x2864d2, 0x4cd260, 0x36eaa6, 0x5ad550,
135                 0x465aa0, 0x30ada5, 0x5695d0, 0x404ad0, 0x2aa9b3, 0x50a4d0, 0x3ad2b7, 0x5eb250, 0x48b540, 0x33d556
136 ); /* Years 2100-2199 */
137
138 var CAN = new Array("Gi\341p", "\u1EA4t", "B\355nh", "\u0110inh", "M\u1EADu", "K\u1EF7", "Canh", "T\342n", "Nh\342m", "Qu\375");
139 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");
140 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");
141 var GIO_HD = new Array("110100101100", "001101001011", "110011010010", "101100110100", "001011001101", "010010110011");
142 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",
143         "H\u1EA1 ch\u00ED", "Ti\u1EC3u th\u1EED", "\u0110\u1EA1i th\u1EED", "L\u1EADp thu", "X\u1EED th\u1EED", "B\u1EA1ch l\u1ED9",
144         "Thu ph\u00E2n", "H\u00E0n l\u1ED9", "S\u01B0\u01A1ng gi\u00E1ng", "L\u1EADp \u0111\u00F4ng", "Ti\u1EC3u tuy\u1EBFt", "\u0110\u1EA1i tuy\u1EBFt",
145         "\u0110\u00F4ng ch\u00ED", "Ti\u1EC3u h\u00E0n", "\u0110\u1EA1i h\u00E0n", "L\u1EADp xu\u00E2n", "V\u0169 Th\u1EE7y", "Kinh tr\u1EADp"
146 );
147
148 var LML,RMM;
149
150 /* Create lunar date object, stores (lunar) date, month, year, leap month indicator, and Julian date number */
151 function LunarDate(dd, mm, yy, leap, jd) {
152         this.day = dd;
153         this.month = mm;
154         this.year = yy;
155         this.leap = leap;
156         this.jd = jd;
157 }
158
159 var PI = Math.PI;
160
161 /* Discard the fractional part of a number, e.g., INT(3.2) = 3 */
162 function INT(d) {
163         return Math.floor(d);
164 }
165
166 function jdn(dd, mm, yy) {
167         var a = INT((14 - mm) / 12);
168         var y = yy+4800-a;
169         var m = mm+12*a-3;
170         var jd = dd + INT((153*m+2)/5) + 365*y + INT(y/4) - INT(y/100) + INT(y/400) - 32045;
171         return jd;
172         //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;
173 }
174
175 function jdn2date(jd) {
176         var Z, A, alpha, B, C, D, E, dd, mm, yyyy, F;
177         Z = jd;
178         if (Z < 2299161) {
179           A = Z;
180         } else {
181           alpha = INT((Z-1867216.25)/36524.25);
182           A = Z + 1 + alpha - INT(alpha/4);
183         }
184         B = A + 1524;
185         C = INT( (B-122.1)/365.25);
186         D = INT( 365.25*C );
187         E = INT( (B-D)/30.6001 );
188         dd = INT(B - D - INT(30.6001*E));
189         if (E < 14) {
190           mm = E - 1;
191         } else {
192           mm = E - 13;
193         }
194         if (mm < 3) {
195           yyyy = C - 4715;
196         } else {
197           yyyy = C - 4716;
198         }
199         return new Array(dd, mm, yyyy);
200 }
201
202 function decodeLunarYear(yy, k) {
203         var monthLengths, regularMonths, offsetOfTet, leapMonth, leapMonthLength, solarNY, currentJD, j, mm;
204         var ly = new Array();
205         monthLengths = new Array(29, 30);
206         var regularMonths = new Array(12);
207         offsetOfTet = k >> 17;
208         leapMonth = k & 0xf;
209         leapMonthLength = monthLengths[k >> 16 & 0x1];
210         solarNY = jdn(1, 1, yy);
211         currentJD = solarNY+offsetOfTet;
212         j = k >> 4;
213         for(var i = 0; i < 12; i++) {
214                 regularMonths[12 - i - 1] = monthLengths[j & 0x1];
215                 j >>= 1;
216         }
217         if (leapMonth == 0) {
218                 for(mm = 1; mm <= 12; mm++) {
219                         ly.push(new LunarDate(1, mm, yy, 0, currentJD));
220                         currentJD += regularMonths[mm-1];
221                 }
222         } else {
223                 for(mm = 1; mm <= leapMonth; mm++) {
224                         ly.push(new LunarDate(1, mm, yy, 0, currentJD));
225                         currentJD += regularMonths[mm-1];
226                 }
227                 ly.push(new LunarDate(1, leapMonth, yy, 1, currentJD));
228                 currentJD += leapMonthLength;
229                 for(mm = leapMonth+1; mm <= 12; mm++) {
230                         ly.push(new LunarDate(1, mm, yy, 0, currentJD));
231                         currentJD += regularMonths[mm-1];
232                 }
233         }
234
235        LML = leapMonthLength;
236        RMM = regularMonths;
237         return ly;
238 }
239
240 function leapMonth(yyyy){
241     var yearCode = getYearCode(yyyy);
242     return yearCode & 0xf;
243 }
244
245 function monthLength(yyyy){
246     var yearCode = getYearCode(yyyy);
247     return yearCode >> 16 & 0x1;
248 }
249
250 function getYearCode(yyyy){
251     var yearCode;
252     if (yyyy < 1900) {
253             yearCode = TK19[yyyy - 1800];
254     } else if (yyyy < 2000) {
255             yearCode = TK20[yyyy - 1900];
256     } else if (yyyy < 2100) {
257             yearCode = TK21[yyyy - 2000];
258     } else {
259             yearCode = TK22[yyyy - 2100];
260     }
261     return yearCode;
262 }
263
264 function getYearInfo(yyyy) {
265         var yearCode;
266         if (yyyy < 1900) {
267                 yearCode = TK19[yyyy - 1800];
268         } else if (yyyy < 2000) {
269                 yearCode = TK20[yyyy - 1900];
270         } else if (yyyy < 2100) {
271                 yearCode = TK21[yyyy - 2000];
272         } else {
273                 yearCode = TK22[yyyy - 2100];
274         }
275         return decodeLunarYear(yyyy, yearCode);
276 }
277
278 var FIRST_DAY = jdn(25, 1, 1800); // Tet am lich 1800
279 var LAST_DAY = jdn(31, 12, 2199);
280
281 function findLunarDate(jd, ly) {
282         if (jd > LAST_DAY || jd < FIRST_DAY || ly[0].jd > jd) {
283                 return new LunarDate(0, 0, 0, 0, jd);
284         }
285         var i = ly.length-1;
286         while (jd < ly[i].jd) {
287                 i--;
288         }
289         var off = jd - ly[i].jd;
290         var ret = new LunarDate(ly[i].day+off, ly[i].month, ly[i].year, ly[i].leap, jd);
291         return ret;
292 }
293
294 function getLunarDate(dd, mm, yyyy) {
295         var ly, jd;
296         if (yyyy < 1800 || 2199 < yyyy) {
297                 //return new LunarDate(0, 0, 0, 0, 0);
298         }
299         ly = getYearInfo(yyyy);
300         jd = jdn(dd, mm, yyyy);
301         if (jd < ly[0].jd) {
302                 ly = getYearInfo(yyyy - 1);
303         }
304         return findLunarDate(jd, ly);
305 }
306
307 /* Compute the longitude of the sun at any time.
308  * Parameter: floating number jdn, the number of days since 1/1/4713 BC noon
309  * Algorithm from: "Astronomical Algorithms" by Jean Meeus, 1998
310  */
311 function SunLongitude(jdn) {
312         var T, T2, dr, M, L0, DL, lambda, theta, omega;
313         T = (jdn - 2451545.0 ) / 36525; // Time in Julian centuries from 2000-01-01 12:00:00 GMT
314         T2 = T*T;
315         dr = PI/180; // degree to radian
316         M = 357.52910 + 35999.05030*T - 0.0001559*T2 - 0.00000048*T*T2; // mean anomaly, degree
317         L0 = 280.46645 + 36000.76983*T + 0.0003032*T2; // mean longitude, degree
318         DL = (1.914600 - 0.004817*T - 0.000014*T2)*Math.sin(dr*M);
319         DL = DL + (0.019993 - 0.000101*T)*Math.sin(dr*2*M) + 0.000290*Math.sin(dr*3*M);
320     theta = L0 + DL; // true longitude, degree
321     // obtain apparent longitude by correcting for nutation and aberration
322     omega = 125.04 - 1934.136 * T;
323     lambda = theta - 0.00569 - 0.00478 * Math.sin(omega * dr);
324     // Convert to radians
325     lambda = lambda*dr;
326         lambda = lambda - PI*2*(INT(lambda/(PI*2))); // Normalize to (0, 2*PI)
327     return lambda;
328 }
329
330 /* Compute the sun segment at start (00:00) of the day with the given integral Julian day number.
331  * The time zone if the time difference between local time and UTC: 7.0 for UTC+7:00.
332  * The function returns a number between 0 and 23.
333  * From the day after March equinox and the 1st major term after March equinox, 0 is returned.
334  * After that, return 1, 2, 3 ...
335  */
336 function getSunLongitude(dayNumber, timeZone) {
337         return INT(SunLongitude(dayNumber - 0.5 - timeZone/24.0) / PI * 12);
338 }
339
340 var today = new Date();
341 //var currentLunarYear = getYearInfo(today.getFullYear());
342 var currentLunarDate = getLunarDate(today.getDate(), today.getMonth()+1, today.getFullYear());
343 var currentMonth = today.getMonth()+1;
344 var currentYear = today.getFullYear();
345
346 function parseQuery(q) {
347         var ret = new Array();
348         if (q.length < 2) return ret;
349         var s = q.substring(1, q.length);
350         var arr = s.split("&");
351         var i, j;
352         for (i = 0; i < arr.length; i++) {
353                 var a = arr[i].split("=");
354                 for (j = 0; j < a.length; j++) {
355                         ret.push(a[j]);
356                 }
357         }
358         return ret;
359 }
360
361 function getSelectedMonth() {
362         var query = window.location.search;
363         var arr = parseQuery(query);
364         var idx;
365         for (idx = 0; idx < arr.length; idx++) {
366                 if (arr[idx] == "mm") {
367                         currentMonth = parseInt(arr[idx+1]);
368                 } else if (arr[idx] == "yy") {
369                         currentYear = parseInt(arr[idx+1]);
370                 }
371         }
372 }
373
374 function getMonth(mm, yy) {
375         var ly1, ly2, tet1, jd1, jd2, mm1, yy1, result, i;
376         if (mm < 12) {
377                 mm1 = mm + 1;
378                 yy1 = yy;
379         } else {
380                 mm1 = 1;
381                 yy1 = yy + 1;
382         }
383         jd1 = jdn(1, mm, yy);
384         jd2 = jdn(1, mm1, yy1);
385         ly1 = getYearInfo(yy);
386         //alert('1/'+mm+'/'+yy+' = '+jd1+'; 1/'+mm1+'/'+yy1+' = '+jd2);
387         tet1 = ly1[0].jd;
388         result = new Array();
389         if (tet1 <= jd1) { /* tet(yy) = tet1 < jd1 < jd2 <= 1.1.(yy+1) < tet(yy+1) */
390                 for (i = jd1; i < jd2; i++) {
391                         result.push(findLunarDate(i, ly1));
392                 }
393         } else if (jd1 < tet1 && jd2 < tet1) { /* tet(yy-1) < jd1 < jd2 < tet1 = tet(yy) */
394                 ly1 = getYearInfo(yy - 1);
395                 for (i = jd1; i < jd2; i++) {
396                         result.push(findLunarDate(i, ly1));
397                 }
398         } else if (jd1 < tet1 && tet1 <= jd2) { /* tet(yy-1) < jd1 < tet1 <= jd2 < tet(yy+1) */
399                 ly2 = getYearInfo(yy - 1);
400                 for (i = jd1; i < tet1; i++) {
401                         result.push(findLunarDate(i, ly2));
402                 }
403                 for (i = tet1; i < jd2; i++) {
404                         result.push(findLunarDate(i, ly1));
405                 }
406         }
407         return result;
408 }
409
410 function getDayName(lunarDate) {
411         if (lunarDate.day == 0) {
412                 return "";
413         }
414         var cc = getCanChi(lunarDate);
415         var s = "Ng\u00E0y " + cc[0] +", th\341ng "+cc[1] + ", n\u0103m " + cc[2];
416         return s;
417 }
418
419 function getYearCanChi(year) {
420         return CAN[(year+6) % 10] + " " + CHI[(year+8) % 12];
421 }
422
423 /*
424  * Can cua gio Chinh Ty (00:00) cua ngay voi JDN nay
425  */
426 function getCanHour0(jdn) {
427         return CAN[(jdn-1)*2 % 10];
428 }
429
430 function getCanChi(lunar) {
431         var dayName, monthName, yearName;
432         dayName = CAN[(lunar.jd + 9) % 10] + " " + CHI[(lunar.jd+1)%12];
433         monthName = CAN[(lunar.year*12+lunar.month+3) % 10] + " " + CHI[(lunar.month+1)%12];
434         if (lunar.leap == 1) {
435                 monthName += " (N)";
436         }
437         yearName = getYearCanChi(lunar.year);
438         return new Array(dayName, monthName, yearName);
439 }
440
441 function getDayString(lunar, solarDay, solarMonth, solarYear) {
442         var s;
443         var dayOfWeek = TUAN[(lunar.jd + 1) % 7];
444         s = dayOfWeek + " " + solarDay + "/" + solarMonth + "/" + solarYear;
445         s += " -+- ";
446         s = s + "Ng\u00E0y " + lunar.day+" th\341ng "+lunar.month;
447         if (lunar.leap == 1) {
448                 s = s + " nhu\u1EADn";
449         }
450         return s;
451 }
452
453 function getTodayString() {
454         var s = getDayString(currentLunarDate, today.getDate(), today.getMonth()+1, today.getFullYear());
455         s += " n\u0103m " + getYearCanChi(currentLunarDate.year);
456         return s;
457 }
458
459 function getCurrentTime() {
460         today = new Date();
461         var Std = today.getHours();
462         var Min = today.getMinutes();
463         var Sec = today.getSeconds();
464         var s1  = ((Std < 10) ? "0" + Std : Std);
465         var s2  = ((Min < 10) ? "0" + Min : Min);
466         //var s3  = ((Sec < 10) ? "0" + Sec : Sec);
467         //return s1 + ":" + s2 + ":" + s3;
468         return s1 + ":" + s2;
469 }
470
471 function getGioHoangDao(jd) {
472         var chiOfDay = (jd+1) % 12;
473         var gioHD = GIO_HD[chiOfDay % 6]; // same values for Ty' (1) and Ngo. (6), for Suu and Mui etc.
474         var ret = "";
475         var count = 0;
476         for (var i = 0; i < 12; i++) {
477                 if (gioHD.charAt(i) == '1') {
478                         ret += CHI[i];
479                         ret += ' ('+(i*2+23)%24+'h-'+(i*2+1)%24+'h)';
480                         if (count++ < 5) ret += ', ';
481                         if (count == 3) ret += '<br>';
482                 }
483         }
484         return ret;
485 }
486
487 function getTHU(jd){
488     return TUAN[(jd+1)%7];
489 }
490
491 function getTHUINT(jd){
492     return (jd+1)%7;
493 }