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