chinese_calendar_utils.dart 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. /**
  2. * author:heqian
  3. * date :20-2-29 下午6:00
  4. * email :wskfjtheqian@163.com
  5. **/
  6. ///农历和阳历转换工具
  7. class CalendarUtils {
  8. /// 农历1900-2100的润大小信息表
  9. /// @Array Of Property
  10. /// @return Hex
  11. static List<int> _lunarInfo = [
  12. 0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0,
  13. 0x09ad0, 0x055d2, //1900-1909
  14. 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2,
  15. 0x095b0, 0x14977, //1910-1919
  16. 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570,
  17. 0x052f2, 0x04970, //1920-1929
  18. 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0,
  19. 0x1c8d7, 0x0c950, //1930-1939
  20. 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2,
  21. 0x0a950, 0x0b557, //1940-1949
  22. 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8,
  23. 0x0e950, 0x06aa0, //1950-1959
  24. 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950,
  25. 0x05b57, 0x056a0, //1960-1969
  26. 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540,
  27. 0x0b6a0, 0x195a6, //1970-1979
  28. 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46,
  29. 0x0ab60, 0x09570, //1980-1989
  30. 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60,
  31. 0x096d5, 0x092e0, //1990-1999
  32. 0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0,
  33. 0x092d0, 0x0cab5, //2000-2009
  34. 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176,
  35. 0x052b0, 0x0a930, //2010-2019
  36. 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260,
  37. 0x0ea65, 0x0d530, //2020-2029
  38. 0x05aa0, 0x076a3, 0x096d0, 0x04afb, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250,
  39. 0x0d520, 0x0dd45, //2030-2039
  40. 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255,
  41. 0x06d20, 0x0ada0, //2040-2049
  42. /**Add By JJonline@JJonline.Cn**/
  43. 0x14b63, 0x09370, 0x049f8, 0x04970, 0x064b0, 0x168a6, 0x0ea50, 0x06b20,
  44. 0x1a6c4, 0x0aae0, //2050-2059
  45. 0x0a2e0, 0x0d2e3, 0x0c960, 0x0d557, 0x0d4a0, 0x0da50, 0x05d55, 0x056a0,
  46. 0x0a6d0, 0x055d4, //2060-2069
  47. 0x052d0, 0x0a9b8, 0x0a950, 0x0b4a0, 0x0b6a6, 0x0ad50, 0x055a0, 0x0aba4,
  48. 0x0a5b0, 0x052b0, //2070-2079
  49. 0x0b273, 0x06930, 0x07337, 0x06aa0, 0x0ad50, 0x14b55, 0x04b60, 0x0a570,
  50. 0x054e4, 0x0d160, //2080-2089
  51. 0x0e968, 0x0d520, 0x0daa0, 0x16aa6, 0x056d0, 0x04ae0, 0x0a9d4, 0x0a2d0,
  52. 0x0d150, 0x0f252, //2090-2099
  53. 0x0d520
  54. ]; //2100
  55. /// 公历每个月份的天数普通表
  56. /// @Array Of Property
  57. /// @return Number
  58. static List<int> _solarMonth = [
  59. 31,
  60. 28,
  61. 31,
  62. 30,
  63. 31,
  64. 30,
  65. 31,
  66. 31,
  67. 30,
  68. 31,
  69. 30,
  70. 31
  71. ];
  72. /// 天干地支之天干速查表
  73. /// @return Cn string
  74. static List<String> _gan = ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"];
  75. /// 天干地支之地支速查表
  76. /// @Array Of Property
  77. /// @return Cn string
  78. static List<String> _zhi = [
  79. "子",
  80. "丑",
  81. "寅",
  82. "卯",
  83. "辰",
  84. "巳",
  85. "午",
  86. "未",
  87. "申",
  88. "酉",
  89. "戌",
  90. "亥"
  91. ];
  92. /// 天干地支之地支速查表<=>生肖
  93. /// @Array Of Property
  94. /// @return Cn string
  95. static List<String> _animals = [
  96. "鼠",
  97. "牛",
  98. "虎",
  99. "兔",
  100. "龙",
  101. "蛇",
  102. "马",
  103. "羊",
  104. "猴",
  105. "鸡",
  106. "狗",
  107. "猪"
  108. ];
  109. /// 阳历节日
  110. static Map<String, String> _festival = {
  111. '1-1': '元旦节',
  112. '2-14': '情人节',
  113. '5-1': '劳动节',
  114. '5-4': '青年节',
  115. '6-1': '儿童节',
  116. '9-10': '教师节',
  117. '10-1': '国庆节',
  118. '12-25': '圣诞节',
  119. '3-8': '妇女节',
  120. '3-12': '植树节',
  121. '4-1': '愚人节',
  122. '5-12': '护士节',
  123. '7-1': '建党节',
  124. '8-1': '建军节',
  125. '12-24': '平安夜',
  126. };
  127. /// 农历节日
  128. static Map<String, String> _lfestival = {
  129. '12-30': '除夕',
  130. '1-1': '春节',
  131. '1-15': '元宵节',
  132. '5-5': '端午节',
  133. '8-15': '中秋节',
  134. '9-9': '重阳节',
  135. };
  136. /// 24节气速查表
  137. /// @Array Of Property
  138. /// @return Cn string
  139. static List<String> _solarTerm = [
  140. "小寒",
  141. "大寒",
  142. "立春",
  143. "雨水",
  144. "惊蛰",
  145. "春分",
  146. "清明",
  147. "谷雨",
  148. "立夏",
  149. "小满",
  150. "芒种",
  151. "夏至",
  152. "小暑",
  153. "大暑",
  154. "立秋",
  155. "处暑",
  156. "白露",
  157. "秋分",
  158. "寒露",
  159. "霜降",
  160. "立冬",
  161. "小雪",
  162. "大雪",
  163. "冬至"
  164. ];
  165. /// 1900-2100各年的24节气日期速查表
  166. /// @Array Of Property
  167. /// @return 0x string For splice
  168. static List<String> _sTermInfo = [
  169. '9778397bd097c36b0b6fc9274c91aa',
  170. '97b6b97bd19801ec9210c965cc920e',
  171. '97bcf97c3598082c95f8c965cc920f',
  172. '97bd0b06bdb0722c965ce1cfcc920f',
  173. 'b027097bd097c36b0b6fc9274c91aa',
  174. '97b6b97bd19801ec9210c965cc920e',
  175. '97bcf97c359801ec95f8c965cc920f',
  176. '97bd0b06bdb0722c965ce1cfcc920f',
  177. 'b027097bd097c36b0b6fc9274c91aa',
  178. '97b6b97bd19801ec9210c965cc920e',
  179. '97bcf97c359801ec95f8c965cc920f',
  180. '97bd0b06bdb0722c965ce1cfcc920f',
  181. 'b027097bd097c36b0b6fc9274c91aa',
  182. '9778397bd19801ec9210c965cc920e',
  183. '97b6b97bd19801ec95f8c965cc920f',
  184. '97bd09801d98082c95f8e1cfcc920f',
  185. '97bd097bd097c36b0b6fc9210c8dc2',
  186. '9778397bd197c36c9210c9274c91aa',
  187. '97b6b97bd19801ec95f8c965cc920e',
  188. '97bd09801d98082c95f8e1cfcc920f',
  189. '97bd097bd097c36b0b6fc9210c8dc2',
  190. '9778397bd097c36c9210c9274c91aa',
  191. '97b6b97bd19801ec95f8c965cc920e',
  192. '97bcf97c3598082c95f8e1cfcc920f',
  193. '97bd097bd097c36b0b6fc9210c8dc2',
  194. '9778397bd097c36c9210c9274c91aa',
  195. '97b6b97bd19801ec9210c965cc920e',
  196. '97bcf97c3598082c95f8c965cc920f',
  197. '97bd097bd097c35b0b6fc920fb0722',
  198. '9778397bd097c36b0b6fc9274c91aa',
  199. '97b6b97bd19801ec9210c965cc920e',
  200. '97bcf97c3598082c95f8c965cc920f',
  201. '97bd097bd097c35b0b6fc920fb0722',
  202. '9778397bd097c36b0b6fc9274c91aa',
  203. '97b6b97bd19801ec9210c965cc920e',
  204. '97bcf97c359801ec95f8c965cc920f',
  205. '97bd097bd097c35b0b6fc920fb0722',
  206. '9778397bd097c36b0b6fc9274c91aa',
  207. '97b6b97bd19801ec9210c965cc920e',
  208. '97bcf97c359801ec95f8c965cc920f',
  209. '97bd097bd097c35b0b6fc920fb0722',
  210. '9778397bd097c36b0b6fc9274c91aa',
  211. '97b6b97bd19801ec9210c965cc920e',
  212. '97bcf97c359801ec95f8c965cc920f',
  213. '97bd097bd07f595b0b6fc920fb0722',
  214. '9778397bd097c36b0b6fc9210c8dc2',
  215. '9778397bd19801ec9210c9274c920e',
  216. '97b6b97bd19801ec95f8c965cc920f',
  217. '97bd07f5307f595b0b0bc920fb0722',
  218. '7f0e397bd097c36b0b6fc9210c8dc2',
  219. '9778397bd097c36c9210c9274c920e',
  220. '97b6b97bd19801ec95f8c965cc920f',
  221. '97bd07f5307f595b0b0bc920fb0722',
  222. '7f0e397bd097c36b0b6fc9210c8dc2',
  223. '9778397bd097c36c9210c9274c91aa',
  224. '97b6b97bd19801ec9210c965cc920e',
  225. '97bd07f1487f595b0b0bc920fb0722',
  226. '7f0e397bd097c36b0b6fc9210c8dc2',
  227. '9778397bd097c36b0b6fc9274c91aa',
  228. '97b6b97bd19801ec9210c965cc920e',
  229. '97bcf7f1487f595b0b0bb0b6fb0722',
  230. '7f0e397bd097c35b0b6fc920fb0722',
  231. '9778397bd097c36b0b6fc9274c91aa',
  232. '97b6b97bd19801ec9210c965cc920e',
  233. '97bcf7f1487f595b0b0bb0b6fb0722',
  234. '7f0e397bd097c35b0b6fc920fb0722',
  235. '9778397bd097c36b0b6fc9274c91aa',
  236. '97b6b97bd19801ec9210c965cc920e',
  237. '97bcf7f1487f531b0b0bb0b6fb0722',
  238. '7f0e397bd097c35b0b6fc920fb0722',
  239. '9778397bd097c36b0b6fc9274c91aa',
  240. '97b6b97bd19801ec9210c965cc920e',
  241. '97bcf7f1487f531b0b0bb0b6fb0722',
  242. '7f0e397bd07f595b0b6fc920fb0722',
  243. '9778397bd097c36b0b6fc9274c91aa',
  244. '97b6b97bd19801ec9210c9274c920e',
  245. '97bcf7f0e47f531b0b0bb0b6fb0722',
  246. '7f0e397bd07f595b0b0bc920fb0722',
  247. '9778397bd097c36b0b6fc9210c91aa',
  248. '97b6b97bd197c36c9210c9274c920e',
  249. '97bcf7f0e47f531b0b0bb0b6fb0722',
  250. '7f0e397bd07f595b0b0bc920fb0722',
  251. '9778397bd097c36b0b6fc9210c8dc2',
  252. '9778397bd097c36c9210c9274c920e',
  253. '97b6b7f0e47f531b0723b0b6fb0722',
  254. '7f0e37f5307f595b0b0bc920fb0722',
  255. '7f0e397bd097c36b0b6fc9210c8dc2',
  256. '9778397bd097c36b0b70c9274c91aa',
  257. '97b6b7f0e47f531b0723b0b6fb0721',
  258. '7f0e37f1487f595b0b0bb0b6fb0722',
  259. '7f0e397bd097c35b0b6fc9210c8dc2',
  260. '9778397bd097c36b0b6fc9274c91aa',
  261. '97b6b7f0e47f531b0723b0b6fb0721',
  262. '7f0e27f1487f595b0b0bb0b6fb0722',
  263. '7f0e397bd097c35b0b6fc920fb0722',
  264. '9778397bd097c36b0b6fc9274c91aa',
  265. '97b6b7f0e47f531b0723b0b6fb0721',
  266. '7f0e27f1487f531b0b0bb0b6fb0722',
  267. '7f0e397bd097c35b0b6fc920fb0722',
  268. '9778397bd097c36b0b6fc9274c91aa',
  269. '97b6b7f0e47f531b0723b0b6fb0721',
  270. '7f0e27f1487f531b0b0bb0b6fb0722',
  271. '7f0e397bd097c35b0b6fc920fb0722',
  272. '9778397bd097c36b0b6fc9274c91aa',
  273. '97b6b7f0e47f531b0723b0b6fb0721',
  274. '7f0e27f1487f531b0b0bb0b6fb0722',
  275. '7f0e397bd07f595b0b0bc920fb0722',
  276. '9778397bd097c36b0b6fc9274c91aa',
  277. '97b6b7f0e47f531b0723b0787b0721',
  278. '7f0e27f0e47f531b0b0bb0b6fb0722',
  279. '7f0e397bd07f595b0b0bc920fb0722',
  280. '9778397bd097c36b0b6fc9210c91aa',
  281. '97b6b7f0e47f149b0723b0787b0721',
  282. '7f0e27f0e47f531b0723b0b6fb0722',
  283. '7f0e397bd07f595b0b0bc920fb0722',
  284. '9778397bd097c36b0b6fc9210c8dc2',
  285. '977837f0e37f149b0723b0787b0721',
  286. '7f07e7f0e47f531b0723b0b6fb0722',
  287. '7f0e37f5307f595b0b0bc920fb0722',
  288. '7f0e397bd097c35b0b6fc9210c8dc2',
  289. '977837f0e37f14998082b0787b0721',
  290. '7f07e7f0e47f531b0723b0b6fb0721',
  291. '7f0e37f1487f595b0b0bb0b6fb0722',
  292. '7f0e397bd097c35b0b6fc9210c8dc2',
  293. '977837f0e37f14998082b0787b06bd',
  294. '7f07e7f0e47f531b0723b0b6fb0721',
  295. '7f0e27f1487f531b0b0bb0b6fb0722',
  296. '7f0e397bd097c35b0b6fc920fb0722',
  297. '977837f0e37f14998082b0787b06bd',
  298. '7f07e7f0e47f531b0723b0b6fb0721',
  299. '7f0e27f1487f531b0b0bb0b6fb0722',
  300. '7f0e397bd097c35b0b6fc920fb0722',
  301. '977837f0e37f14998082b0787b06bd',
  302. '7f07e7f0e47f531b0723b0b6fb0721',
  303. '7f0e27f1487f531b0b0bb0b6fb0722',
  304. '7f0e397bd07f595b0b0bc920fb0722',
  305. '977837f0e37f14998082b0787b06bd',
  306. '7f07e7f0e47f531b0723b0b6fb0721',
  307. '7f0e27f1487f531b0b0bb0b6fb0722',
  308. '7f0e397bd07f595b0b0bc920fb0722',
  309. '977837f0e37f14998082b0787b06bd',
  310. '7f07e7f0e47f149b0723b0787b0721',
  311. '7f0e27f0e47f531b0b0bb0b6fb0722',
  312. '7f0e397bd07f595b0b0bc920fb0722',
  313. '977837f0e37f14998082b0723b06bd',
  314. '7f07e7f0e37f149b0723b0787b0721',
  315. '7f0e27f0e47f531b0723b0b6fb0722',
  316. '7f0e397bd07f595b0b0bc920fb0722',
  317. '977837f0e37f14898082b0723b02d5',
  318. '7ec967f0e37f14998082b0787b0721',
  319. '7f07e7f0e47f531b0723b0b6fb0722',
  320. '7f0e37f1487f595b0b0bb0b6fb0722',
  321. '7f0e37f0e37f14898082b0723b02d5',
  322. '7ec967f0e37f14998082b0787b0721',
  323. '7f07e7f0e47f531b0723b0b6fb0722',
  324. '7f0e37f1487f531b0b0bb0b6fb0722',
  325. '7f0e37f0e37f14898082b0723b02d5',
  326. '7ec967f0e37f14998082b0787b06bd',
  327. '7f07e7f0e47f531b0723b0b6fb0721',
  328. '7f0e37f1487f531b0b0bb0b6fb0722',
  329. '7f0e37f0e37f14898082b072297c35',
  330. '7ec967f0e37f14998082b0787b06bd',
  331. '7f07e7f0e47f531b0723b0b6fb0721',
  332. '7f0e27f1487f531b0b0bb0b6fb0722',
  333. '7f0e37f0e37f14898082b072297c35',
  334. '7ec967f0e37f14998082b0787b06bd',
  335. '7f07e7f0e47f531b0723b0b6fb0721',
  336. '7f0e27f1487f531b0b0bb0b6fb0722',
  337. '7f0e37f0e366aa89801eb072297c35',
  338. '7ec967f0e37f14998082b0787b06bd',
  339. '7f07e7f0e47f149b0723b0787b0721',
  340. '7f0e27f1487f531b0b0bb0b6fb0722',
  341. '7f0e37f0e366aa89801eb072297c35',
  342. '7ec967f0e37f14998082b0723b06bd',
  343. '7f07e7f0e47f149b0723b0787b0721',
  344. '7f0e27f0e47f531b0723b0b6fb0722',
  345. '7f0e37f0e366aa89801eb072297c35',
  346. '7ec967f0e37f14998082b0723b06bd',
  347. '7f07e7f0e37f14998083b0787b0721',
  348. '7f0e27f0e47f531b0723b0b6fb0722',
  349. '7f0e37f0e366aa89801eb072297c35',
  350. '7ec967f0e37f14898082b0723b02d5',
  351. '7f07e7f0e37f14998082b0787b0721',
  352. '7f07e7f0e47f531b0723b0b6fb0722',
  353. '7f0e36665b66aa89801e9808297c35',
  354. '665f67f0e37f14898082b0723b02d5',
  355. '7ec967f0e37f14998082b0787b0721',
  356. '7f07e7f0e47f531b0723b0b6fb0722',
  357. '7f0e36665b66a449801e9808297c35',
  358. '665f67f0e37f14898082b0723b02d5',
  359. '7ec967f0e37f14998082b0787b06bd',
  360. '7f07e7f0e47f531b0723b0b6fb0721',
  361. '7f0e36665b66a449801e9808297c35',
  362. '665f67f0e37f14898082b072297c35',
  363. '7ec967f0e37f14998082b0787b06bd',
  364. '7f07e7f0e47f531b0723b0b6fb0721',
  365. '7f0e26665b66a449801e9808297c35',
  366. '665f67f0e37f1489801eb072297c35',
  367. '7ec967f0e37f14998082b0787b06bd',
  368. '7f07e7f0e47f531b0723b0b6fb0721',
  369. '7f0e27f1487f531b0b0bb0b6fb0722'
  370. ];
  371. static List<String> _nStr1 = [
  372. '日',
  373. '一',
  374. '二',
  375. '三',
  376. '四',
  377. '五',
  378. '六',
  379. '七',
  380. '八',
  381. '九',
  382. '十'
  383. ];
  384. static List<String> _nStr2 = ['初', '十', '廿', '卅'];
  385. static List<String> _nStr3 = [
  386. '正',
  387. '一',
  388. '二',
  389. '三',
  390. '四',
  391. '五',
  392. '六',
  393. '七',
  394. '八',
  395. '九',
  396. '十',
  397. '冬',
  398. '腊'
  399. ];
  400. static List<String> _nStr4 = [
  401. '魔羯',
  402. '水瓶',
  403. '双鱼',
  404. '白羊',
  405. '金牛',
  406. '双子',
  407. '巨蟹',
  408. '狮子',
  409. '处女',
  410. '天秤',
  411. '天蝎',
  412. '射手',
  413. '魔羯'
  414. ];
  415. /// 返回农历y年一整年的总天数
  416. static int lYearDays(int year) {
  417. var i, sum = 348;
  418. for (i = 0x8000; i > 0x8; i >>= 1) {
  419. sum += (0 != (_lunarInfo[year - 1900] & i) ? 1 : 0);
  420. }
  421. return (sum + leapDays(year));
  422. }
  423. /// 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
  424. static int leapMonth(int year) {
  425. return (_lunarInfo[year - 1900] & 0xf);
  426. }
  427. /// 返回农历y年闰月的天数 若该年没有闰月则返回0
  428. static int leapDays(int year, [int? month]) {
  429. if (0 != leapMonth(year)) {
  430. return (0 != (_lunarInfo[year - 1900] & 0x10000) ? 30 : 29);
  431. }
  432. return 0;
  433. }
  434. /// 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
  435. static int monthDays(int year, int month) {
  436. if (month > 12 || month < 1) {
  437. return -1;
  438. }
  439. return (0 != (_lunarInfo[year - 1900] & (0x10000 >> month)) ? 30 : 29);
  440. }
  441. /// 返回公历(!)y年m月的天数
  442. static int _solarDays(int year, int month) {
  443. if (month > 12 || month < 1) {
  444. return -1;
  445. }
  446. var ms = month - 1;
  447. if (ms == 1) {
  448. return (((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0))
  449. ? 29
  450. : 28);
  451. } else {
  452. return (_solarMonth[ms]);
  453. }
  454. }
  455. /// 农历年份转换为干支纪年
  456. static String toGanZhiYear(int lYear) {
  457. var ganKey = (lYear - 3) % 10;
  458. var zhiKey = (lYear - 3) % 12;
  459. if (ganKey == 0) ganKey = 10; //如果余数为0则为最后一个天干
  460. if (zhiKey == 0) zhiKey = 12; //如果余数为0则为最后一个地支
  461. return _gan[ganKey - 1] + _zhi[zhiKey - 1];
  462. }
  463. /// 公历月、日判断所属星座
  464. static String toAstro(int cMonth, int cDay) {
  465. var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22];
  466. return _nStr4[cMonth - (cDay < arr[cMonth - 1] ? 1 : 0)] + "座";
  467. }
  468. /// 传入offset偏移量返回干支
  469. static String toGanZhi(int offset) {
  470. return _gan[offset % 10] + _zhi[offset % 12];
  471. }
  472. /// 传入公历(!)y年获得该年第n个节气的公历日期
  473. static int getTerm(int year, int n) {
  474. if (year < 1900 || year > 2100) {
  475. return -1;
  476. }
  477. if (n < 1 || n > 24) {
  478. return -1;
  479. }
  480. var _table = _sTermInfo[year - 1900];
  481. var _info = [
  482. int.parse(_table.substring(0, 5), radix: 16).toString(),
  483. int.parse(_table.substring(5, 10), radix: 16).toString(),
  484. int.parse(_table.substring(10, 15), radix: 16).toString(),
  485. int.parse(_table.substring(15, 20), radix: 16).toString(),
  486. int.parse(_table.substring(20, 25), radix: 16).toString(),
  487. int.parse(_table.substring(25, 30), radix: 16).toString()
  488. ];
  489. var _calday = [
  490. _info[0].substring(0, 1),
  491. _info[0].substring(1, 3),
  492. _info[0].substring(3, 4),
  493. _info[0].substring(4, 6),
  494. _info[1].substring(0, 1),
  495. _info[1].substring(1, 3),
  496. _info[1].substring(3, 4),
  497. _info[1].substring(4, 6),
  498. _info[2].substring(0, 1),
  499. _info[2].substring(1, 3),
  500. _info[2].substring(3, 4),
  501. _info[2].substring(4, 6),
  502. _info[3].substring(0, 1),
  503. _info[3].substring(1, 3),
  504. _info[3].substring(3, 4),
  505. _info[3].substring(4, 6),
  506. _info[4].substring(0, 1),
  507. _info[4].substring(1, 3),
  508. _info[4].substring(3, 4),
  509. _info[4].substring(4, 6),
  510. _info[5].substring(0, 1),
  511. _info[5].substring(1, 3),
  512. _info[5].substring(3, 4),
  513. _info[5].substring(4, 6),
  514. ];
  515. return int.parse(_calday[n - 1]);
  516. }
  517. /// 传入农历数字月份返回汉语通俗表示法
  518. static String? toChinaMonth(int month) {
  519. if (month > 12 || month < 1) {
  520. return null;
  521. }
  522. var s = _nStr3[month];
  523. s += "月";
  524. return s;
  525. }
  526. /// 传入农历日期数字返回汉字表示法
  527. static String toChinaDay(int day) {
  528. var s;
  529. switch (day) {
  530. case 10:
  531. s = '初十';
  532. break;
  533. case 20:
  534. s = '二十';
  535. break;
  536. break;
  537. case 30:
  538. s = '三十';
  539. break;
  540. break;
  541. default:
  542. s = _nStr2[(day / 10).floor()];
  543. s += _nStr1[day % 10];
  544. }
  545. return (s);
  546. }
  547. /// 传入阳历年月日获得详细的公历、农历object信息
  548. /// 参数区间1900.1.31~2100.12.31
  549. static DateTime? solar2lunar(DateTime solarDate) {
  550. int year = solarDate.year;
  551. int month = solarDate.month;
  552. int day = solarDate.day;
  553. //年份限定、上限
  554. if (year < 1900 || year > 2100) {
  555. return null;
  556. }
  557. //公历传参最下限
  558. if (year == 1900 && month == 1 && day < 31) {
  559. return null;
  560. }
  561. int offset = solarDate.difference(DateTime(1900, 1, 31)).inDays;
  562. int i, temp = 0;
  563. for (i = 1900; i < 2101 && offset > 0; i++) {
  564. temp = lYearDays(i);
  565. offset -= temp;
  566. }
  567. if (offset < 0) {
  568. offset += temp;
  569. i--;
  570. }
  571. year = i;
  572. int leap = leapMonth(i); //闰哪个月
  573. var isLeap = false;
  574. //效验闰月
  575. for (i = 1; i < 13 && offset > 0; i++) {
  576. //闰月
  577. if (leap > 0 && i == (leap + 1) && isLeap == false) {
  578. --i;
  579. isLeap = true;
  580. temp = leapDays(year); //计算农历闰月天数
  581. } else {
  582. temp = monthDays(year, i); //计算农历普通月天数
  583. }
  584. //解除闰月
  585. if (isLeap == true && i == (leap + 1)) {
  586. isLeap = false;
  587. }
  588. offset -= temp;
  589. }
  590. // 闰月导致数组下标重叠取反
  591. if (offset == 0 && leap > 0 && i == leap + 1) {
  592. if (isLeap) {
  593. isLeap = false;
  594. } else {
  595. isLeap = true;
  596. --i;
  597. }
  598. }
  599. if (offset < 0) {
  600. offset += temp;
  601. --i;
  602. }
  603. month = i;
  604. day = offset + 1;
  605. return DateTime(year, month, day);
  606. }
  607. static CalendarInfo getInfo(DateTime solarDate) {
  608. var lunarDate = solar2lunar(solarDate);
  609. String gzYear = toGanZhiYear(solarDate.year);
  610. var firstNode =
  611. getTerm(solarDate.year, (solarDate.month * 2 - 1)); //返回当月「节」为几日开始
  612. var secondNode =
  613. getTerm(solarDate.year, (solarDate.month * 2)); //返回当月「节」为几日开始
  614. // 依据12节气修正干支月
  615. var gzMonth = toGanZhi((solarDate.year - 1900) * 12 + solarDate.month + 11);
  616. if (solarDate.day >= firstNode) {
  617. gzMonth = toGanZhi((solarDate.year - 1900) * 12 + solarDate.month + 12);
  618. }
  619. //日柱 当月一日与 1900/1/1 相差天数
  620. var dayCyclical = DateTime(solarDate.year, solarDate.month, 1)
  621. .difference(DateTime(1900))
  622. .inDays;
  623. var gzDay = toGanZhi(dayCyclical + solarDate.day + 9);
  624. //传入的日期的节气与否
  625. var term;
  626. if (firstNode == solarDate.day) {
  627. term = _solarTerm[solarDate.month * 2 - 2];
  628. }
  629. if (secondNode == solarDate.day) {
  630. term = _solarTerm[solarDate.month * 2 - 1];
  631. }
  632. return CalendarInfo(
  633. lunarDate: lunarDate,
  634. solarDate: solarDate,
  635. // animal: getAnimal(solarDate.year),
  636. astro: toAstro(solarDate.month, solarDate.day),
  637. lunarYearName: toGanZhiYear(lunarDate!.year),
  638. lunarMonthName: toChinaMonth(lunarDate.month),
  639. lunarDayName: toChinaDay(lunarDate.day),
  640. gzYear: gzYear,
  641. gzMonth: gzMonth,
  642. gzDay: gzDay,
  643. term: term,
  644. festival: _festival['${solarDate.month}-${solarDate.day}'],
  645. lunarFestival: _lfestival['${lunarDate.month}-${lunarDate.day}'],
  646. );
  647. }
  648. static int compareDate(DateTime date1, DateTime date2) {
  649. if (null == date1 || null == date2) {
  650. return 0;
  651. }
  652. if (date1.year > date2.year) {
  653. return 1;
  654. } else if (date1.year < date2.year) {
  655. return -1;
  656. } else if (date1.month > date2.month) {
  657. return 1;
  658. } else if (date1.month < date2.month) {
  659. return -1;
  660. } else if (date1.day > date2.day) {
  661. return 1;
  662. } else if (date1.day < date2.day) {
  663. return -1;
  664. }
  665. return 0;
  666. }
  667. }
  668. class CalendarInfo {
  669. ///农历日期
  670. final DateTime? lunarDate;
  671. ///公历日期
  672. final DateTime? solarDate;
  673. final String? lunarYearName;
  674. final String? lunarMonthName;
  675. final String? lunarDayName;
  676. //生肖
  677. final String? animal;
  678. //星座
  679. final String? astro;
  680. final String? gzYear;
  681. final String? gzMonth;
  682. final String? gzDay;
  683. final String? term;
  684. final String? festival;
  685. final String? lunarFestival;
  686. CalendarInfo({
  687. this.lunarDate,
  688. this.solarDate,
  689. this.lunarYearName,
  690. this.lunarMonthName,
  691. this.lunarDayName,
  692. this.animal,
  693. this.astro,
  694. this.gzYear,
  695. this.gzMonth,
  696. this.gzDay,
  697. this.term,
  698. this.festival,
  699. this.lunarFestival,
  700. });
  701. }