chinese_calendar_utils.dart 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  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 final 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 final 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 final List<String> _gan = [
  75. "甲",
  76. "乙",
  77. "丙",
  78. "丁",
  79. "戊",
  80. "己",
  81. "庚",
  82. "辛",
  83. "壬",
  84. "癸"
  85. ];
  86. /// 天干地支之地支速查表
  87. /// @Array Of Property
  88. /// @return Cn string
  89. static final List<String> _zhi = [
  90. "子",
  91. "丑",
  92. "寅",
  93. "卯",
  94. "辰",
  95. "巳",
  96. "午",
  97. "未",
  98. "申",
  99. "酉",
  100. "戌",
  101. "亥"
  102. ];
  103. /// 阳历节日
  104. static final Map<String, String> _festival = {
  105. '1-1': '元旦节',
  106. '2-14': '情人节',
  107. '5-1': '劳动节',
  108. '5-4': '青年节',
  109. '6-1': '儿童节',
  110. '9-10': '教师节',
  111. '10-1': '国庆节',
  112. '12-25': '圣诞节',
  113. '3-8': '妇女节',
  114. '3-12': '植树节',
  115. '4-1': '愚人节',
  116. '5-12': '护士节',
  117. '7-1': '建党节',
  118. '8-1': '建军节',
  119. '12-24': '平安夜',
  120. };
  121. /// 农历节日
  122. static final Map<String, String> _lfestival = {
  123. '12-30': '除夕',
  124. '1-1': '春节',
  125. '1-15': '元宵节',
  126. '5-5': '端午节',
  127. '8-15': '中秋节',
  128. '9-9': '重阳节',
  129. };
  130. /// 24节气速查表
  131. /// @Array Of Property
  132. /// @return Cn string
  133. static final List<String> _solarTerm = [
  134. "小寒",
  135. "大寒",
  136. "立春",
  137. "雨水",
  138. "惊蛰",
  139. "春分",
  140. "清明",
  141. "谷雨",
  142. "立夏",
  143. "小满",
  144. "芒种",
  145. "夏至",
  146. "小暑",
  147. "大暑",
  148. "立秋",
  149. "处暑",
  150. "白露",
  151. "秋分",
  152. "寒露",
  153. "霜降",
  154. "立冬",
  155. "小雪",
  156. "大雪",
  157. "冬至"
  158. ];
  159. /// 1900-2100各年的24节气日期速查表
  160. /// @Array Of Property
  161. /// @return 0x string For splice
  162. static final List<String> _sTermInfo = [
  163. '9778397bd097c36b0b6fc9274c91aa',
  164. '97b6b97bd19801ec9210c965cc920e',
  165. '97bcf97c3598082c95f8c965cc920f',
  166. '97bd0b06bdb0722c965ce1cfcc920f',
  167. 'b027097bd097c36b0b6fc9274c91aa',
  168. '97b6b97bd19801ec9210c965cc920e',
  169. '97bcf97c359801ec95f8c965cc920f',
  170. '97bd0b06bdb0722c965ce1cfcc920f',
  171. 'b027097bd097c36b0b6fc9274c91aa',
  172. '97b6b97bd19801ec9210c965cc920e',
  173. '97bcf97c359801ec95f8c965cc920f',
  174. '97bd0b06bdb0722c965ce1cfcc920f',
  175. 'b027097bd097c36b0b6fc9274c91aa',
  176. '9778397bd19801ec9210c965cc920e',
  177. '97b6b97bd19801ec95f8c965cc920f',
  178. '97bd09801d98082c95f8e1cfcc920f',
  179. '97bd097bd097c36b0b6fc9210c8dc2',
  180. '9778397bd197c36c9210c9274c91aa',
  181. '97b6b97bd19801ec95f8c965cc920e',
  182. '97bd09801d98082c95f8e1cfcc920f',
  183. '97bd097bd097c36b0b6fc9210c8dc2',
  184. '9778397bd097c36c9210c9274c91aa',
  185. '97b6b97bd19801ec95f8c965cc920e',
  186. '97bcf97c3598082c95f8e1cfcc920f',
  187. '97bd097bd097c36b0b6fc9210c8dc2',
  188. '9778397bd097c36c9210c9274c91aa',
  189. '97b6b97bd19801ec9210c965cc920e',
  190. '97bcf97c3598082c95f8c965cc920f',
  191. '97bd097bd097c35b0b6fc920fb0722',
  192. '9778397bd097c36b0b6fc9274c91aa',
  193. '97b6b97bd19801ec9210c965cc920e',
  194. '97bcf97c3598082c95f8c965cc920f',
  195. '97bd097bd097c35b0b6fc920fb0722',
  196. '9778397bd097c36b0b6fc9274c91aa',
  197. '97b6b97bd19801ec9210c965cc920e',
  198. '97bcf97c359801ec95f8c965cc920f',
  199. '97bd097bd097c35b0b6fc920fb0722',
  200. '9778397bd097c36b0b6fc9274c91aa',
  201. '97b6b97bd19801ec9210c965cc920e',
  202. '97bcf97c359801ec95f8c965cc920f',
  203. '97bd097bd097c35b0b6fc920fb0722',
  204. '9778397bd097c36b0b6fc9274c91aa',
  205. '97b6b97bd19801ec9210c965cc920e',
  206. '97bcf97c359801ec95f8c965cc920f',
  207. '97bd097bd07f595b0b6fc920fb0722',
  208. '9778397bd097c36b0b6fc9210c8dc2',
  209. '9778397bd19801ec9210c9274c920e',
  210. '97b6b97bd19801ec95f8c965cc920f',
  211. '97bd07f5307f595b0b0bc920fb0722',
  212. '7f0e397bd097c36b0b6fc9210c8dc2',
  213. '9778397bd097c36c9210c9274c920e',
  214. '97b6b97bd19801ec95f8c965cc920f',
  215. '97bd07f5307f595b0b0bc920fb0722',
  216. '7f0e397bd097c36b0b6fc9210c8dc2',
  217. '9778397bd097c36c9210c9274c91aa',
  218. '97b6b97bd19801ec9210c965cc920e',
  219. '97bd07f1487f595b0b0bc920fb0722',
  220. '7f0e397bd097c36b0b6fc9210c8dc2',
  221. '9778397bd097c36b0b6fc9274c91aa',
  222. '97b6b97bd19801ec9210c965cc920e',
  223. '97bcf7f1487f595b0b0bb0b6fb0722',
  224. '7f0e397bd097c35b0b6fc920fb0722',
  225. '9778397bd097c36b0b6fc9274c91aa',
  226. '97b6b97bd19801ec9210c965cc920e',
  227. '97bcf7f1487f595b0b0bb0b6fb0722',
  228. '7f0e397bd097c35b0b6fc920fb0722',
  229. '9778397bd097c36b0b6fc9274c91aa',
  230. '97b6b97bd19801ec9210c965cc920e',
  231. '97bcf7f1487f531b0b0bb0b6fb0722',
  232. '7f0e397bd097c35b0b6fc920fb0722',
  233. '9778397bd097c36b0b6fc9274c91aa',
  234. '97b6b97bd19801ec9210c965cc920e',
  235. '97bcf7f1487f531b0b0bb0b6fb0722',
  236. '7f0e397bd07f595b0b6fc920fb0722',
  237. '9778397bd097c36b0b6fc9274c91aa',
  238. '97b6b97bd19801ec9210c9274c920e',
  239. '97bcf7f0e47f531b0b0bb0b6fb0722',
  240. '7f0e397bd07f595b0b0bc920fb0722',
  241. '9778397bd097c36b0b6fc9210c91aa',
  242. '97b6b97bd197c36c9210c9274c920e',
  243. '97bcf7f0e47f531b0b0bb0b6fb0722',
  244. '7f0e397bd07f595b0b0bc920fb0722',
  245. '9778397bd097c36b0b6fc9210c8dc2',
  246. '9778397bd097c36c9210c9274c920e',
  247. '97b6b7f0e47f531b0723b0b6fb0722',
  248. '7f0e37f5307f595b0b0bc920fb0722',
  249. '7f0e397bd097c36b0b6fc9210c8dc2',
  250. '9778397bd097c36b0b70c9274c91aa',
  251. '97b6b7f0e47f531b0723b0b6fb0721',
  252. '7f0e37f1487f595b0b0bb0b6fb0722',
  253. '7f0e397bd097c35b0b6fc9210c8dc2',
  254. '9778397bd097c36b0b6fc9274c91aa',
  255. '97b6b7f0e47f531b0723b0b6fb0721',
  256. '7f0e27f1487f595b0b0bb0b6fb0722',
  257. '7f0e397bd097c35b0b6fc920fb0722',
  258. '9778397bd097c36b0b6fc9274c91aa',
  259. '97b6b7f0e47f531b0723b0b6fb0721',
  260. '7f0e27f1487f531b0b0bb0b6fb0722',
  261. '7f0e397bd097c35b0b6fc920fb0722',
  262. '9778397bd097c36b0b6fc9274c91aa',
  263. '97b6b7f0e47f531b0723b0b6fb0721',
  264. '7f0e27f1487f531b0b0bb0b6fb0722',
  265. '7f0e397bd097c35b0b6fc920fb0722',
  266. '9778397bd097c36b0b6fc9274c91aa',
  267. '97b6b7f0e47f531b0723b0b6fb0721',
  268. '7f0e27f1487f531b0b0bb0b6fb0722',
  269. '7f0e397bd07f595b0b0bc920fb0722',
  270. '9778397bd097c36b0b6fc9274c91aa',
  271. '97b6b7f0e47f531b0723b0787b0721',
  272. '7f0e27f0e47f531b0b0bb0b6fb0722',
  273. '7f0e397bd07f595b0b0bc920fb0722',
  274. '9778397bd097c36b0b6fc9210c91aa',
  275. '97b6b7f0e47f149b0723b0787b0721',
  276. '7f0e27f0e47f531b0723b0b6fb0722',
  277. '7f0e397bd07f595b0b0bc920fb0722',
  278. '9778397bd097c36b0b6fc9210c8dc2',
  279. '977837f0e37f149b0723b0787b0721',
  280. '7f07e7f0e47f531b0723b0b6fb0722',
  281. '7f0e37f5307f595b0b0bc920fb0722',
  282. '7f0e397bd097c35b0b6fc9210c8dc2',
  283. '977837f0e37f14998082b0787b0721',
  284. '7f07e7f0e47f531b0723b0b6fb0721',
  285. '7f0e37f1487f595b0b0bb0b6fb0722',
  286. '7f0e397bd097c35b0b6fc9210c8dc2',
  287. '977837f0e37f14998082b0787b06bd',
  288. '7f07e7f0e47f531b0723b0b6fb0721',
  289. '7f0e27f1487f531b0b0bb0b6fb0722',
  290. '7f0e397bd097c35b0b6fc920fb0722',
  291. '977837f0e37f14998082b0787b06bd',
  292. '7f07e7f0e47f531b0723b0b6fb0721',
  293. '7f0e27f1487f531b0b0bb0b6fb0722',
  294. '7f0e397bd097c35b0b6fc920fb0722',
  295. '977837f0e37f14998082b0787b06bd',
  296. '7f07e7f0e47f531b0723b0b6fb0721',
  297. '7f0e27f1487f531b0b0bb0b6fb0722',
  298. '7f0e397bd07f595b0b0bc920fb0722',
  299. '977837f0e37f14998082b0787b06bd',
  300. '7f07e7f0e47f531b0723b0b6fb0721',
  301. '7f0e27f1487f531b0b0bb0b6fb0722',
  302. '7f0e397bd07f595b0b0bc920fb0722',
  303. '977837f0e37f14998082b0787b06bd',
  304. '7f07e7f0e47f149b0723b0787b0721',
  305. '7f0e27f0e47f531b0b0bb0b6fb0722',
  306. '7f0e397bd07f595b0b0bc920fb0722',
  307. '977837f0e37f14998082b0723b06bd',
  308. '7f07e7f0e37f149b0723b0787b0721',
  309. '7f0e27f0e47f531b0723b0b6fb0722',
  310. '7f0e397bd07f595b0b0bc920fb0722',
  311. '977837f0e37f14898082b0723b02d5',
  312. '7ec967f0e37f14998082b0787b0721',
  313. '7f07e7f0e47f531b0723b0b6fb0722',
  314. '7f0e37f1487f595b0b0bb0b6fb0722',
  315. '7f0e37f0e37f14898082b0723b02d5',
  316. '7ec967f0e37f14998082b0787b0721',
  317. '7f07e7f0e47f531b0723b0b6fb0722',
  318. '7f0e37f1487f531b0b0bb0b6fb0722',
  319. '7f0e37f0e37f14898082b0723b02d5',
  320. '7ec967f0e37f14998082b0787b06bd',
  321. '7f07e7f0e47f531b0723b0b6fb0721',
  322. '7f0e37f1487f531b0b0bb0b6fb0722',
  323. '7f0e37f0e37f14898082b072297c35',
  324. '7ec967f0e37f14998082b0787b06bd',
  325. '7f07e7f0e47f531b0723b0b6fb0721',
  326. '7f0e27f1487f531b0b0bb0b6fb0722',
  327. '7f0e37f0e37f14898082b072297c35',
  328. '7ec967f0e37f14998082b0787b06bd',
  329. '7f07e7f0e47f531b0723b0b6fb0721',
  330. '7f0e27f1487f531b0b0bb0b6fb0722',
  331. '7f0e37f0e366aa89801eb072297c35',
  332. '7ec967f0e37f14998082b0787b06bd',
  333. '7f07e7f0e47f149b0723b0787b0721',
  334. '7f0e27f1487f531b0b0bb0b6fb0722',
  335. '7f0e37f0e366aa89801eb072297c35',
  336. '7ec967f0e37f14998082b0723b06bd',
  337. '7f07e7f0e47f149b0723b0787b0721',
  338. '7f0e27f0e47f531b0723b0b6fb0722',
  339. '7f0e37f0e366aa89801eb072297c35',
  340. '7ec967f0e37f14998082b0723b06bd',
  341. '7f07e7f0e37f14998083b0787b0721',
  342. '7f0e27f0e47f531b0723b0b6fb0722',
  343. '7f0e37f0e366aa89801eb072297c35',
  344. '7ec967f0e37f14898082b0723b02d5',
  345. '7f07e7f0e37f14998082b0787b0721',
  346. '7f07e7f0e47f531b0723b0b6fb0722',
  347. '7f0e36665b66aa89801e9808297c35',
  348. '665f67f0e37f14898082b0723b02d5',
  349. '7ec967f0e37f14998082b0787b0721',
  350. '7f07e7f0e47f531b0723b0b6fb0722',
  351. '7f0e36665b66a449801e9808297c35',
  352. '665f67f0e37f14898082b0723b02d5',
  353. '7ec967f0e37f14998082b0787b06bd',
  354. '7f07e7f0e47f531b0723b0b6fb0721',
  355. '7f0e36665b66a449801e9808297c35',
  356. '665f67f0e37f14898082b072297c35',
  357. '7ec967f0e37f14998082b0787b06bd',
  358. '7f07e7f0e47f531b0723b0b6fb0721',
  359. '7f0e26665b66a449801e9808297c35',
  360. '665f67f0e37f1489801eb072297c35',
  361. '7ec967f0e37f14998082b0787b06bd',
  362. '7f07e7f0e47f531b0723b0b6fb0721',
  363. '7f0e27f1487f531b0b0bb0b6fb0722'
  364. ];
  365. static final List<String> _nStr1 = [
  366. '日',
  367. '一',
  368. '二',
  369. '三',
  370. '四',
  371. '五',
  372. '六',
  373. '七',
  374. '八',
  375. '九',
  376. '十'
  377. ];
  378. static final List<String> _nStr2 = ['初', '十', '廿', '卅'];
  379. static final List<String> _nStr3 = [
  380. '正',
  381. '一',
  382. '二',
  383. '三',
  384. '四',
  385. '五',
  386. '六',
  387. '七',
  388. '八',
  389. '九',
  390. '十',
  391. '冬',
  392. '腊'
  393. ];
  394. static final List<String> _nStr4 = [
  395. '魔羯',
  396. '水瓶',
  397. '双鱼',
  398. '白羊',
  399. '金牛',
  400. '双子',
  401. '巨蟹',
  402. '狮子',
  403. '处女',
  404. '天秤',
  405. '天蝎',
  406. '射手',
  407. '魔羯'
  408. ];
  409. /// 返回农历y年一整年的总天数
  410. static int lYearDays(int year) {
  411. var i, sum = 348;
  412. for (i = 0x8000; i > 0x8; i >>= 1) {
  413. sum += (0 != (_lunarInfo[year - 1900] & i) ? 1 : 0);
  414. }
  415. return (sum + leapDays(year));
  416. }
  417. /// 返回农历y年闰月是哪个月;若y年没有闰月 则返回0
  418. static int leapMonth(int year) {
  419. return (_lunarInfo[year - 1900] & 0xf);
  420. }
  421. /// 返回农历y年闰月的天数 若该年没有闰月则返回0
  422. static int leapDays(int year, [int? month]) {
  423. if (0 != leapMonth(year)) {
  424. return (0 != (_lunarInfo[year - 1900] & 0x10000) ? 30 : 29);
  425. }
  426. return 0;
  427. }
  428. /// 返回农历y年m月(非闰月)的总天数,计算m为闰月时的天数请使用leapDays方法
  429. static int monthDays(int year, int month) {
  430. if (month > 12 || month < 1) {
  431. return -1;
  432. }
  433. return (0 != (_lunarInfo[year - 1900] & (0x10000 >> month)) ? 30 : 29);
  434. }
  435. /// 返回公历(!)y年m月的天数
  436. static int _solarDays(int year, int month) {
  437. if (month > 12 || month < 1) {
  438. return -1;
  439. }
  440. var ms = month - 1;
  441. if (ms == 1) {
  442. return (((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0))
  443. ? 29
  444. : 28);
  445. } else {
  446. return (_solarMonth[ms]);
  447. }
  448. }
  449. /// 农历年份转换为干支纪年
  450. static String toGanZhiYear(int lYear) {
  451. var ganKey = (lYear - 3) % 10;
  452. var zhiKey = (lYear - 3) % 12;
  453. if (ganKey == 0) ganKey = 10; //如果余数为0则为最后一个天干
  454. if (zhiKey == 0) zhiKey = 12; //如果余数为0则为最后一个地支
  455. return _gan[ganKey - 1] + _zhi[zhiKey - 1];
  456. }
  457. /// 公历月、日判断所属星座
  458. static String toAstro(int cMonth, int cDay) {
  459. var arr = [20, 19, 21, 21, 21, 22, 23, 23, 23, 23, 22, 22];
  460. return _nStr4[cMonth - (cDay < arr[cMonth - 1] ? 1 : 0)] + "座";
  461. }
  462. /// 传入offset偏移量返回干支
  463. static String toGanZhi(int offset) {
  464. return _gan[offset % 10] + _zhi[offset % 12];
  465. }
  466. /// 传入公历(!)y年获得该年第n个节气的公历日期
  467. static int getTerm(int year, int n) {
  468. if (year < 1900 || year > 2100) {
  469. return -1;
  470. }
  471. if (n < 1 || n > 24) {
  472. return -1;
  473. }
  474. var _table = _sTermInfo[year - 1900];
  475. var _info = [
  476. int.parse(_table.substring(0, 5), radix: 16).toString(),
  477. int.parse(_table.substring(5, 10), radix: 16).toString(),
  478. int.parse(_table.substring(10, 15), radix: 16).toString(),
  479. int.parse(_table.substring(15, 20), radix: 16).toString(),
  480. int.parse(_table.substring(20, 25), radix: 16).toString(),
  481. int.parse(_table.substring(25, 30), radix: 16).toString()
  482. ];
  483. var _calday = [
  484. _info[0].substring(0, 1),
  485. _info[0].substring(1, 3),
  486. _info[0].substring(3, 4),
  487. _info[0].substring(4, 6),
  488. _info[1].substring(0, 1),
  489. _info[1].substring(1, 3),
  490. _info[1].substring(3, 4),
  491. _info[1].substring(4, 6),
  492. _info[2].substring(0, 1),
  493. _info[2].substring(1, 3),
  494. _info[2].substring(3, 4),
  495. _info[2].substring(4, 6),
  496. _info[3].substring(0, 1),
  497. _info[3].substring(1, 3),
  498. _info[3].substring(3, 4),
  499. _info[3].substring(4, 6),
  500. _info[4].substring(0, 1),
  501. _info[4].substring(1, 3),
  502. _info[4].substring(3, 4),
  503. _info[4].substring(4, 6),
  504. _info[5].substring(0, 1),
  505. _info[5].substring(1, 3),
  506. _info[5].substring(3, 4),
  507. _info[5].substring(4, 6),
  508. ];
  509. return int.parse(_calday[n - 1]);
  510. }
  511. /// 传入农历数字月份返回汉语通俗表示法
  512. static String? toChinaMonth(int month) {
  513. if (month > 12 || month < 1) {
  514. return null;
  515. }
  516. var s = _nStr3[month];
  517. s += "月";
  518. return s;
  519. }
  520. /// 传入农历日期数字返回汉字表示法
  521. static String toChinaDay(int day) {
  522. var s = '';
  523. switch (day) {
  524. case 10:
  525. s = '初十';
  526. break;
  527. case 20:
  528. s = '二十';
  529. break;
  530. case 30:
  531. s = '三十';
  532. break;
  533. default:
  534. s = _nStr2[(day / 10).floor()];
  535. s += _nStr1[day % 10];
  536. }
  537. return (s);
  538. }
  539. /// 传入阳历年月日获得详细的公历、农历object信息
  540. /// 参数区间1900.1.31~2100.12.31
  541. static DateTime? solar2lunar(DateTime solarDate) {
  542. int year = solarDate.year;
  543. int month = solarDate.month;
  544. int day = solarDate.day;
  545. //年份限定、上限
  546. if (year < 1900 || year > 2100) {
  547. return null;
  548. }
  549. //公历传参最下限
  550. if (year == 1900 && month == 1 && day < 31) {
  551. return null;
  552. }
  553. int offset = solarDate.difference(DateTime(1900, 1, 31)).inDays;
  554. int i, temp = 0;
  555. for (i = 1900; i < 2101 && offset > 0; i++) {
  556. temp = lYearDays(i);
  557. offset -= temp;
  558. }
  559. if (offset < 0) {
  560. offset += temp;
  561. i--;
  562. }
  563. year = i;
  564. int leap = leapMonth(i); //闰哪个月
  565. var isLeap = false;
  566. //效验闰月
  567. for (i = 1; i < 13 && offset > 0; i++) {
  568. //闰月
  569. if (leap > 0 && i == (leap + 1) && isLeap == false) {
  570. --i;
  571. isLeap = true;
  572. temp = leapDays(year); //计算农历闰月天数
  573. } else {
  574. temp = monthDays(year, i); //计算农历普通月天数
  575. }
  576. //解除闰月
  577. if (isLeap == true && i == (leap + 1)) {
  578. isLeap = false;
  579. }
  580. offset -= temp;
  581. }
  582. // 闰月导致数组下标重叠取反
  583. if (offset == 0 && leap > 0 && i == leap + 1) {
  584. if (isLeap) {
  585. isLeap = false;
  586. } else {
  587. isLeap = true;
  588. --i;
  589. }
  590. }
  591. if (offset < 0) {
  592. offset += temp;
  593. --i;
  594. }
  595. month = i;
  596. day = offset + 1;
  597. return DateTime(year, month, day);
  598. }
  599. static CalendarInfo getInfo(DateTime solarDate) {
  600. var lunarDate = solar2lunar(solarDate);
  601. String gzYear = toGanZhiYear(solarDate.year);
  602. var firstNode =
  603. getTerm(solarDate.year, (solarDate.month * 2 - 1)); //返回当月「节」为几日开始
  604. var secondNode =
  605. getTerm(solarDate.year, (solarDate.month * 2)); //返回当月「节」为几日开始
  606. // 依据12节气修正干支月
  607. var gzMonth = toGanZhi((solarDate.year - 1900) * 12 + solarDate.month + 11);
  608. if (solarDate.day >= firstNode) {
  609. gzMonth = toGanZhi((solarDate.year - 1900) * 12 + solarDate.month + 12);
  610. }
  611. //日柱 当月一日与 1900/1/1 相差天数
  612. var dayCyclical = DateTime(solarDate.year, solarDate.month, 1)
  613. .difference(DateTime(1900))
  614. .inDays;
  615. var gzDay = toGanZhi(dayCyclical + solarDate.day + 9);
  616. //传入的日期的节气与否
  617. var term;
  618. if (firstNode == solarDate.day) {
  619. term = _solarTerm[solarDate.month * 2 - 2];
  620. }
  621. if (secondNode == solarDate.day) {
  622. term = _solarTerm[solarDate.month * 2 - 1];
  623. }
  624. return CalendarInfo(
  625. lunarDate: lunarDate,
  626. solarDate: solarDate,
  627. lunarYearName: toGanZhiYear(lunarDate!.year),
  628. lunarMonthName: toChinaMonth(lunarDate.month),
  629. lunarDayName: toChinaDay(lunarDate.day),
  630. term: term,
  631. festival: _festival['${solarDate.month}-${solarDate.day}'],
  632. lunarFestival: _lfestival['${lunarDate.month}-${lunarDate.day}'],
  633. );
  634. }
  635. static int compareDate(DateTime date1, DateTime date2) {
  636. if (null == date1 || null == date2) {
  637. return 0;
  638. }
  639. if (date1.year > date2.year) {
  640. return 1;
  641. } else if (date1.year < date2.year) {
  642. return -1;
  643. } else if (date1.month > date2.month) {
  644. return 1;
  645. } else if (date1.month < date2.month) {
  646. return -1;
  647. } else if (date1.day > date2.day) {
  648. return 1;
  649. } else if (date1.day < date2.day) {
  650. return -1;
  651. }
  652. return 0;
  653. }
  654. }
  655. class CalendarInfo {
  656. ///农历日期
  657. final DateTime? lunarDate;
  658. ///公历日期
  659. final DateTime? solarDate;
  660. final String? lunarYearName;
  661. final String? lunarMonthName;
  662. final String? lunarDayName;
  663. final String? term;
  664. final String? festival;
  665. final String? lunarFestival;
  666. CalendarInfo({
  667. this.lunarDate,
  668. this.solarDate,
  669. this.lunarYearName,
  670. this.lunarMonthName,
  671. this.lunarDayName,
  672. this.term,
  673. this.festival,
  674. this.lunarFestival,
  675. });
  676. }