1 package com.example.nanchen.mydateviewdemo.view; java.util.Calendar; * 主要用于把公历日期处理成24节气 nanchen 8 * @date 16-8-10 上午11:38 SolarTermsUtil { * 计算得到公历的年份 gregorianYear; * 计算得到公历的月份 gregorianMonth; * 用于计算得到公历的日期 gregorianDate; chineseYear; chineseMonth; chineseDate; 初始日,公历农历对应日期: baseYear = 1901; baseMonth = 1; baseDate = 1; baseIndex = 0; baseChineseYear = 4598 - 1; baseChineseMonth = 11; baseChineseDate = 11; [] daysInGregorianMonth = { 31, 28, 31, 30, 31, 30, 31, 40 31, 30, 31, 30, 31 }; sectionalTerm; principleTerm; [][] sectionalTermMap = { 46 { 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 5, 5, 47 5, 5, 5, 4, 5, 5 }, 48 { 5, 4, 5, 5, 5, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 4, 4, 4, 3, 49 3, 4, 4, 3, 3, 3 }, 50 { 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5, 51 5, 5, 4, 5, 5, 5, 5 }, 52 { 5, 5, 6, 6, 5, 5, 5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 4, 4, 5, 5, 4, 4, 53 4, 5, 4, 4, 4, 4, 5 }, 54 { 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 5, 6, 5, 5, 55 5, 5, 4, 5, 5, 5, 5 }, 56 { 6, 6, 7, 7, 6, 6, 6, 7, 6, 6, 6, 6, 5, 6, 6, 6, 5, 5, 6, 6, 5, 5, 57 5, 6, 5, 5, 5, 5, 4, 5, 5, 5, 5 }, 58 { 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6, 59 7, 7, 6, 6, 6, 7, 7 }, 60 { 8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 61 7, 7, 6, 7, 7, 7, 6, 6, 7, 7, 7 }, 62 { 8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 63 7, 7, 6, 7, 7, 7, 7 }, 64 { 9, 9, 9, 9, 8, 9, 9, 9, 8, 8, 9, 9, 8, 8, 8, 9, 8, 8, 8, 8, 7, 8, 65 8, 8, 7, 7, 8, 8, 8 }, 66 { 8, 8, 8, 8, 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 67 7, 7, 6, 6, 7, 7, 7 }, 68 { 7, 8, 8, 8, 7, 7, 8, 8, 7, 7, 7, 8, 7, 7, 7, 7, 6, 7, 7, 7, 6, 6, 69 7, 7, 6, 6, 6, 7, 7 } }; [][] sectionalTermYear = { 71 { 13, 49, 85, 117, 149, 185, 201, 250, 250 }, 72 { 13, 45, 81, 117, 149, 185, 201, 250, 250 }, 73 { 13, 48, 84, 112, 148, 184, 200, 201, 250 }, 74 { 13, 45, 76, 108, 140, 172, 200, 201, 250 }, 75 { 13, 44, 72, 104, 132, 168, 200, 201, 250 }, 76 { 5, 33, 68, 96, 124, 152, 188, 200, 201 }, 77 { 29, 57, 85, 120, 148, 176, 200, 201, 250 }, 78 { 13, 48, 76, 104, 132, 168, 196, 200, 201 }, 79 { 25, 60, 88, 120, 148, 184, 200, 201, 250 }, 80 { 16, 44, 76, 108, 144, 172, 200, 201, 250 }, 81 { 28, 60, 92, 124, 160, 192, 200, 201, 250 }, 82 { 17, 53, 85, 124, 156, 188, 200, 201, 250 } }; [][] principleTermMap = { 84 { 21, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 85 20, 20, 20, 20, 20, 19, 20, 20, 20, 19, 19, 20 }, 86 { 20, 19, 19, 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 18, 19, 19, 87 19, 18, 18, 19, 19, 18, 18, 18, 18, 18, 18, 18 }, 88 { 21, 21, 21, 22, 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 89 20, 20, 20, 21, 20, 20, 20, 20, 19, 20, 20, 20, 20 }, 90 { 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 20, 20, 20, 20, 91 19, 20, 20, 20, 19, 19, 20, 20, 19, 19, 19, 20, 20 }, 92 { 21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21, 93 20, 21, 21, 21, 20, 20, 21, 21, 20, 20, 20, 21, 21 }, 94 { 22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 21, 21, 21, 22, 95 21, 21, 21, 21, 20, 21, 21, 21, 20, 20, 21, 21, 21 }, 96 { 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23, 22, 23, 23, 23, 97 22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 23 }, 98 { 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23, 99 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 23 }, 100 { 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 23, 23, 23, 23, 101 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 23 }, 102 { 24, 24, 24, 24, 23, 24, 24, 24, 23, 23, 24, 24, 23, 23, 23, 24, 103 23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 23 }, 104 { 23, 23, 23, 23, 22, 23, 23, 23, 22, 22, 23, 23, 22, 22, 22, 23, 105 22, 22, 22, 22, 21, 22, 22, 22, 21, 21, 22, 22, 22 }, 106 { 22, 22, 23, 23, 22, 22, 22, 23, 22, 22, 22, 22, 21, 22, 22, 22, 107 21, 21, 22, 22, 21, 21, 21, 22, 21, 21, 21, 21, 22 } }; [][] principleTermYear = { 109 { 13, 45, 81, 113, 149, 185, 201 }, 110 { 21, 57, 93, 125, 161, 193, 201 }, 111 { 21, 56, 88, 120, 152, 188, 200, 201 }, 112 { 21, 49, 81, 116, 144, 176, 200, 201 }, 113 { 17, 49, 77, 112, 140, 168, 200, 201 }, 114 { 28, 60, 88, 116, 148, 180, 200, 201 }, 115 { 25, 53, 84, 112, 144, 172, 200, 201 }, 116 { 29, 57, 89, 120, 148, 180, 200, 201 }, 117 { 17, 45, 73, 108, 140, 168, 200, 201 }, 118 { 28, 60, 92, 124, 160, 192, 200, 201 }, 119 { 16, 44, 80, 112, 148, 180, 200, 201 }, 120 { 17, 53, 88, 120, 156, 188, 200, 201 } }; [] chineseMonths = { 123 // 农历月份大小压缩表,两个字节表示一年。两个字节共十六个二进制位数, 0x00, 0x04, 0xad, 0x08, 0x5a, 0x01, 0xd5, 0x54, 0xb4, 0x09, 0x64, 126 0x05, 0x59, 0x45, 0x95, 0x0a, 0xa6, 0x04, 0x55, 0x24, 0xad, 0x08, 127 0x5a, 0x62, 0xda, 0x04, 0xb4, 0x05, 0xb4, 0x55, 0x52, 0x0d, 0x94, 128 0x0a, 0x4a, 0x2a, 0x56, 0x02, 0x6d, 0x71, 0x6d, 0x01, 0xda, 0x02, 129 0xd2, 0x52, 0xa9, 0x05, 0x49, 0x0d, 0x2a, 0x45, 0x2b, 0x09, 0x56, 130 0x01, 0xb5, 0x20, 0x6d, 0x01, 0x59, 0x69, 0xd4, 0x0a, 0xa8, 0x05, 131 0xa9, 0x56, 0xa5, 0x04, 0x2b, 0x09, 0x9e, 0x38, 0xb6, 0x08, 0xec, 132 0x74, 0x6c, 0x05, 0xd4, 0x0a, 0xe4, 0x6a, 0x52, 0x05, 0x95, 0x0a, 133 0x5a, 0x42, 0x5b, 0x04, 0xb6, 0x04, 0xb4, 0x22, 0x6a, 0x05, 0x52, 134 0x75, 0xc9, 0x0a, 0x52, 0x05, 0x35, 0x55, 0x4d, 0x0a, 0x5a, 0x02, 135 0x5d, 0x31, 0xb5, 0x02, 0x6a, 0x8a, 0x68, 0x05, 0xa9, 0x0a, 0x8a, 136 0x6a, 0x2a, 0x05, 0x2d, 0x09, 0xaa, 0x48, 0x5a, 0x01, 0xb5, 0x09, 137 0xb0, 0x39, 0x64, 0x05, 0x25, 0x75, 0x95, 0x0a, 0x96, 0x04, 0x4d, 138 0x54, 0xad, 0x04, 0xda, 0x04, 0xd4, 0x44, 0xb4, 0x05, 0x54, 0x85, 139 0x52, 0x0d, 0x92, 0x0a, 0x56, 0x6a, 0x56, 0x02, 0x6d, 0x02, 0x6a, 140 0x41, 0xda, 0x02, 0xb2, 0xa1, 0xa9, 0x05, 0x49, 0x0d, 0x0a, 0x6d, 141 0x2a, 0x09, 0x56, 0x01, 0xad, 0x50, 0x6d, 0x01, 0xd9, 0x02, 0xd1, 142 0x3a, 0xa8, 0x05, 0x29, 0x85, 0xa5, 0x0c, 0x2a, 0x09, 0x96, 0x54, 143 0xb6, 0x08, 0x6c, 0x09, 0x64, 0x45, 0xd4, 0x0a, 0xa4, 0x05, 0x51, 144 0x25, 0x95, 0x0a, 0x2a, 0x72, 0x5b, 0x04, 0xb6, 0x04, 0xac, 0x52, 145 0x6a, 0x05, 0xd2, 0x0a, 0xa2, 0x4a, 0x4a, 0x05, 0x55, 0x94, 0x2d, 146 0x0a, 0x5a, 0x02, 0x75, 0x61, 0xb5, 0x02, 0x6a, 0x03, 0x61, 0x45, 147 0xa9, 0x0a, 0x4a, 0x05, 0x25, 0x25, 0x2d, 0x09, 0x9a, 0x68, 0xda, 148 0x08, 0xb4, 0x09, 0xa8, 0x59, 0x54, 0x03, 0xa5, 0x0a, 0x91, 0x3a, 149 0x96, 0x04, 0xad, 0xb0, 0xad, 0x04, 0xda, 0x04, 0xf4, 0x62, 0xb4, 150 0x05, 0x54, 0x0b, 0x44, 0x5d, 0x52, 0x0a, 0x95, 0x04, 0x55, 0x22, 151 0x6d, 0x02, 0x5a, 0x71, 0xda, 0x02, 0xaa, 0x05, 0xb2, 0x55, 0x49, 152 0x0b, 0x4a, 0x0a, 0x2d, 0x39, 0x36, 0x01, 0x6d, 0x80, 0x6d, 0x01, 153 0xd9, 0x02, 0xe9, 0x6a, 0xa8, 0x05, 0x29, 0x0b, 0x9a, 0x4c, 0xaa, 154 0x08, 0xb6, 0x08, 0xb4, 0x38, 0x6c, 0x09, 0x54, 0x75, 0xd4, 0x0a, 155 0xa4, 0x05, 0x45, 0x55, 0x95, 0x0a, 0x9a, 0x04, 0x55, 0x44, 0xb5, 156 0x04, 0x6a, 0x82, 0x6a, 0x05, 0xd2, 0x0a, 0x92, 0x6a, 0x4a, 0x05, 157 0x55, 0x0a, 0x2a, 0x4a, 0x5a, 0x02, 0xb5, 0x02, 0xb2, 0x31, 0x69, 158 0x03, 0x31, 0x73, 0xa9, 0x0a, 0x4a, 0x05, 0x2d, 0x55, 0x2d, 0x09, 159 0x5a, 0x01, 0xd5, 0x48, 0xb4, 0x09, 0x68, 0x89, 0x54, 0x0b, 0xa4, 160 0x0a, 0xa5, 0x6a, 0x95, 0x04, 0xad, 0x08, 0x6a, 0x44, 0xda, 0x04, 161 0x74, 0x05, 0xb0, 0x25, 0x54, 0x03 }; * 用于保存24节气 String[] principleTermNames = { "大寒", "雨水", "春分", "谷雨", 167 "小满", "夏至", "大暑", "处暑", "秋分", "霜降", "小雪", "冬至" }; * 用于保存24节气 String[] sectionalTermNames = { "小寒", "立春", "惊蛰", "清明", 172 "立夏", "芒种", "小暑", "立秋", "白露", "寒露", "立冬", "大雪" }; SolarTermsUtil(Calendar calendar) { 175 gregorianYear = calendar.get(Calendar.YEAR); 176 gregorianMonth = calendar.get(Calendar.MONTH) + 1; 177 gregorianDate = calendar.get(Calendar.DATE); 178 computeChineseFields(); 179 computeSolarTerms(); 180 } computeChineseFields() { 183 if (gregorianYear < 1901 || gregorianYear > 2100) 184 return 1; 185 int startYear = baseYear; 186 int startMonth = baseMonth; 187 int startDate = baseDate; 188 chineseYear = baseChineseYear; 189 chineseMonth = baseChineseMonth; 190 chineseDate = baseChineseDate; 191 // 第二个对应日,用以提高计算效率 (gregorianYear >= 2000) { 194 startYear = baseYear + 99; 195 startMonth = 1; 196 startDate = 1; 197 chineseYear = baseChineseYear + 99; 198 chineseMonth = 11; 199 chineseDate = 25; 200 } 201 int daysDiff = 0; 202 for (int i = startYear; i < gregorianYear; i++) { 203 daysDiff += 365; 204 if (isGregorianLeapYear(i)) } 207 for (int i = startMonth; i < gregorianMonth; i++) { 208 daysDiff += daysInGregorianMonth(gregorianYear, i); 209 } 210 daysDiff += gregorianDate - startDate; 211 212 chineseDate += daysDiff; 213 int lastDate = daysInChineseMonth(chineseYear, chineseMonth); 214 int nextMonth = nextChineseMonth(chineseYear, chineseMonth); 215 while (chineseDate > lastDate) { 216 if (Math.abs(nextMonth) < Math.abs(chineseMonth)) 217 chineseYear++; 218 chineseMonth = nextMonth; 219 chineseDate -= lastDate; 220 lastDate = daysInChineseMonth(chineseYear, chineseMonth); 221 nextMonth = nextChineseMonth(chineseYear, chineseMonth); 222 } 223 return 0; 224 } computeSolarTerms() { 227 if (gregorianYear < 1901 || gregorianYear > 2100) 228 return 1; 229 sectionalTerm = sectionalTerm(gregorianYear, gregorianMonth); 230 principleTerm = principleTerm(gregorianYear, gregorianMonth); 231 return 0; 232 } sectionalTerm(int y, int m) { 235 if (y < 1901 || y > 2100) 236 return 0; 237 int index = 0; 238 int ry = y - baseYear + 1; 239 while (ry >= sectionalTermYear[m - 1][index]) 240 index++; 241 int term = sectionalTermMap[m - 1][4 * index + ry % 4]; 242 if ((ry == 121) && (m == 4)) 243 term = 5; 244 if ((ry == 132) && (m == 4)) 245 term = 5; 246 if ((ry == 194) && (m == 6)) 247 term = 6; 248 return term; 249 } principleTerm(int y, int m) { 252 if (y < 1901 || y > 2100) 253 return 0; 254 int index = 0; 255 int ry = y - baseYear + 1; 256 while (ry >= principleTermYear[m - 1][index]) 257 index++; 258 int term = principleTermMap[m - 1][4 * index + ry % 4]; 259 if ((ry == 171) && (m == 3)) 260 term = 21; 261 if ((ry == 181) && (m == 5)) 262 term = 21; 263 return term; 264 } * 用于判断输入的年份是否为闰年 268 * year 270 * 输入的年份 true 表示闰年 isGregorianLeapYear(int year) { 274 boolean isLeap = false; 275 if (year % 4 == 0) 276 isLeap = true; 277 if (year % 100 == 0) 278 isLeap = false; 279 if (year % 400 == 0) 280 isLeap = true; 281 return isLeap; 282 } daysInGregorianMonth(int y, int m) { 285 int d = daysInGregorianMonth[m - 1]; 286 if (m == 2 && isGregorianLeapYear(y)) d; 289 } daysInChineseMonth(int y, int m) { index = y - baseChineseYear + baseIndex; 294 int v = 0; 295 int l = 0; 296 int d = 30; 297 if (1 <= m && m <= 8) { 298 v = chineseMonths[2 * index]; 299 l = m - 1; 300 if (((v >> l) & 0x01) == 1) 301 d = 29; 302 } else if (9 <= m && m <= 12) { 303 v = chineseMonths[2 * index + 1]; 304 l = m - 9; 305 if (((v >> l) & 0x01) == 1) 306 d = 29; 307 } else { 308 v = chineseMonths[2 * index + 1]; 309 v = (v >> 4) & 0x0F; 310 if (v != Math.abs(m)) { 311 d = 0; 312 } else { 313 d = 29; 314 for (int i = 0; i < bigLeapMonthYears.length; i++) { 315 if (bigLeapMonthYears[i] == index) { 316 d = 30; 317 break; 318 } 319 } 320 } 321 } 322 return d; 323 } nextChineseMonth(int y, int m) { 326 int n = Math.abs(m) + 1; 327 if (m > 0) { 328 int index = y - baseChineseYear + baseIndex; 329 int v = chineseMonths[2 * index + 1]; 330 v = (v >> 4) & 0x0F; 331 if (v == m) 332 n = -m; 333 } 334 if (n == 13) 335 n = 1; 336 return n; 337 } [] bigLeapMonthYears = { 6, 14, 19, 25, 33, 36, 38, 41, 341 44, 52, 55, 79, 117, 136, 147, 150, 155, 158, 185, 193 }; * 用于获取24节气的值 345 * 24节气的值 String getSolartermsMsg() { 349 String str = ""; 350 String gm = String.valueOf(gregorianMonth); 351 if (gm.length() == 1) 352 gm = ' ' + gm; 353 String cm = String.valueOf(Math.abs(chineseMonth)); 354 if (cm.length() == 1) 355 cm = ' ' + cm; 356 String gd = String.valueOf(gregorianDate); 357 if (gd.length() == 1) 358 gd = ' ' + gd; 359 String cd = String.valueOf(chineseDate); 360 if (cd.length() == 1) 361 cd = ' ' + cd; 362 if (gregorianDate == sectionalTerm) { 363 str = " " + sectionalTermNames[gregorianMonth - 1]; 364 } else if (gregorianDate == principleTerm) { 365 str = " " + principleTermNames[gregorianMonth - 1]; 366 } 367 return str; 368 } 369 }
8)
StringUtil