Нет описания
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

LunarMonth.cs 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. using System;
  2. using Lunar.Util;
  3. // ReSharper disable MemberCanBePrivate.Global
  4. namespace Lunar
  5. {
  6. /// <summary>
  7. /// 农历月
  8. /// </summary>
  9. public class LunarMonth
  10. {
  11. /// <summary>
  12. /// 农历年
  13. /// </summary>
  14. public int Year { get; }
  15. /// <summary>
  16. /// 农历月:1-12,闰月为负数,如闰2月为-2
  17. /// </summary>
  18. public int Month { get; }
  19. /// <summary>
  20. /// 天数,大月30天,小月29天
  21. /// </summary>
  22. public int DayCount { get; }
  23. /// <summary>
  24. /// 初一的儒略日
  25. /// </summary>
  26. public double FirstJulianDay { get; }
  27. /// <summary>
  28. /// 序号
  29. /// </summary>
  30. public int Index { get; }
  31. /// <summary>
  32. /// 地支序号
  33. /// </summary>
  34. public int ZhiIndex { get; }
  35. /// <summary>
  36. /// 初始化
  37. /// </summary>
  38. /// <param name="lunarYear">农历年</param>
  39. /// <param name="lunarMonth">农历月:1-12,闰月为负数,如闰2月为-2</param>
  40. /// <param name="dayCount">天数</param>
  41. /// <param name="firstJulianDay">初一的儒略日</param>
  42. /// <param name="index">序号</param>
  43. public LunarMonth(int lunarYear, int lunarMonth, int dayCount, double firstJulianDay, int index)
  44. {
  45. Year = lunarYear;
  46. Month = lunarMonth;
  47. DayCount = dayCount;
  48. FirstJulianDay = firstJulianDay;
  49. Index = index;
  50. ZhiIndex = (index - 1 + LunarUtil.BASE_MONTH_ZHI_INDEX) % 12;
  51. }
  52. /// <summary>
  53. /// 通过农历年月初始化
  54. /// </summary>
  55. /// <param name="lunarYear">农历年</param>
  56. /// <param name="lunarMonth">农历月:1-12,闰月为负数,如闰2月为-2</param>
  57. /// <returns>农历月</returns>
  58. public static LunarMonth FromYm(int lunarYear, int lunarMonth)
  59. {
  60. return LunarYear.FromYear(lunarYear).GetMonth(lunarMonth);
  61. }
  62. /// <summary>
  63. /// 是否闰月
  64. /// </summary>
  65. public bool Leap => Month < 0;
  66. /// <summary>
  67. /// 天干序号
  68. /// </summary>
  69. public int GanIndex
  70. {
  71. get
  72. {
  73. var offset = (LunarYear.FromYear(Year).GanIndex + 1) % 5 * 2;
  74. return (Index - 1 + offset) % 10;
  75. }
  76. }
  77. /// <summary>
  78. /// 天干
  79. /// </summary>
  80. public string Gan => LunarUtil.GAN[GanIndex + 1];
  81. /// <summary>
  82. /// 地支
  83. /// </summary>
  84. public string Zhi => LunarUtil.ZHI[ZhiIndex + 1];
  85. /// <summary>
  86. /// 干支
  87. /// </summary>
  88. public string GanZhi => $"{Gan}{Zhi}";
  89. /// <summary>
  90. /// 喜神方位
  91. /// </summary>
  92. public string PositionXi => LunarUtil.POSITION_XI[GanIndex + 1];
  93. /// <summary>
  94. /// 喜神方位描述
  95. /// </summary>
  96. public string PositionXiDesc => LunarUtil.POSITION_DESC[PositionXi];
  97. /// <summary>
  98. /// 阳贵神方位
  99. /// </summary>
  100. public string PositionYangGui => LunarUtil.POSITION_YANG_GUI[GanIndex + 1];
  101. /// <summary>
  102. /// 阳贵神方位描述
  103. /// </summary>
  104. public string PositionYangGuiDesc => LunarUtil.POSITION_DESC[PositionYangGui];
  105. /// <summary>
  106. /// 阴贵神方位
  107. /// </summary>
  108. public string PositionYinGui => LunarUtil.POSITION_YIN_GUI[GanIndex + 1];
  109. /// <summary>
  110. /// 阴贵神方位描述
  111. /// </summary>
  112. public string PositionYinGuiDesc => LunarUtil.POSITION_DESC[PositionYinGui];
  113. /// <summary>
  114. /// 福神方位
  115. /// </summary>
  116. public string PositionFu => GetPositionFu();
  117. /// <summary>
  118. /// 福神方位
  119. /// </summary>
  120. /// <param name="sect">流派</param>
  121. /// <returns>福神方位</returns>
  122. public string GetPositionFu(int sect = 2) {
  123. return (1 == sect ? LunarUtil.POSITION_FU : LunarUtil.POSITION_FU_2)[GanIndex + 1];
  124. }
  125. /// <summary>
  126. /// 福神方位描述
  127. /// </summary>
  128. public string PositionFuDesc => GetPositionFuDesc();
  129. /// <summary>
  130. /// 福神方位描述
  131. /// </summary>
  132. /// <param name="sect">流派</param>
  133. /// <returns>方位描述</returns>
  134. public string GetPositionFuDesc(int sect = 2) {
  135. return LunarUtil.POSITION_DESC[GetPositionFu(sect)];
  136. }
  137. /// <summary>
  138. /// 财神方位
  139. /// </summary>
  140. public string PositionCai => LunarUtil.POSITION_CAI[GanIndex + 1];
  141. /// <summary>
  142. /// 财神方位描述
  143. /// </summary>
  144. public string PositionCaiDesc => LunarUtil.POSITION_DESC[PositionCai];
  145. /// <summary>
  146. /// 太岁方位,如艮
  147. /// </summary>
  148. public string PositionTaiSui
  149. {
  150. get
  151. {
  152. string p;
  153. var m = Math.Abs(Month);
  154. switch (m)
  155. {
  156. case 1:
  157. case 5:
  158. case 9:
  159. p = "艮";
  160. break;
  161. case 3:
  162. case 7:
  163. case 11:
  164. p = "坤";
  165. break;
  166. case 4:
  167. case 8:
  168. case 12:
  169. p = "巽";
  170. break;
  171. default:
  172. p = LunarUtil.POSITION_GAN[Solar.FromJulianDay(FirstJulianDay).Lunar.MonthGanIndex];
  173. break;
  174. }
  175. return p;
  176. }
  177. }
  178. /// <summary>
  179. /// 太岁方位描述,如东北
  180. /// </summary>
  181. public string PositionTaiSuiDesc => LunarUtil.POSITION_DESC[PositionTaiSui];
  182. /// <summary>
  183. /// 九星
  184. /// </summary>
  185. public NineStar NineStar
  186. {
  187. get
  188. {
  189. var index = LunarYear.FromYear(Year).ZhiIndex % 3;
  190. var m = Math.Abs(Month);
  191. var monthZhiIndex = (13 + m) % 12;
  192. var n = 27 - (index * 3);
  193. if (monthZhiIndex < LunarUtil.BASE_MONTH_ZHI_INDEX)
  194. {
  195. n -= 3;
  196. }
  197. var offset = (n - monthZhiIndex) % 9;
  198. return NineStar.FromIndex(offset);
  199. }
  200. }
  201. /// <inheritdoc />
  202. public override string ToString()
  203. {
  204. return Year + "年" + (Leap ? "闰" : "") + LunarUtil.MONTH[Math.Abs(Month)] + "月(" + DayCount + "天)";
  205. }
  206. /// <summary>
  207. /// 推移
  208. /// </summary>
  209. /// <param name="n">月数</param>
  210. /// <returns>农历月</returns>
  211. public LunarMonth Next(int n)
  212. {
  213. if (0 == n)
  214. {
  215. return FromYm(Year, Month);
  216. }
  217. if (n > 0)
  218. {
  219. var rest = n;
  220. var ny = Year;
  221. var iy = ny;
  222. var im = Month;
  223. var index = 0;
  224. var months = LunarYear.FromYear(ny).Months;
  225. while (true)
  226. {
  227. var size = months.Count;
  228. for (var i = 0; i < size; i++)
  229. {
  230. var m = months[i];
  231. if (m.Year != iy || m.Month != im) continue;
  232. index = i;
  233. break;
  234. }
  235. var more = size - index - 1;
  236. if (rest < more)
  237. {
  238. break;
  239. }
  240. rest -= more;
  241. var lastMonth = months[size - 1];
  242. iy = lastMonth.Year;
  243. im = lastMonth.Month;
  244. ny++;
  245. months = LunarYear.FromYear(ny).Months;
  246. }
  247. return months[index + rest];
  248. }
  249. else
  250. {
  251. var rest = -n;
  252. var ny = Year;
  253. var iy = ny;
  254. var im = Month;
  255. var index = 0;
  256. var months = LunarYear.FromYear(ny).Months;
  257. while (true)
  258. {
  259. var size = months.Count;
  260. for (var i = 0; i < size; i++)
  261. {
  262. var m = months[i];
  263. if (m.Year != iy || m.Month != im) continue;
  264. index = i;
  265. break;
  266. }
  267. if (rest <= index)
  268. {
  269. break;
  270. }
  271. rest -= index;
  272. var firstMonth = months[0];
  273. iy = firstMonth.Year;
  274. im = firstMonth.Month;
  275. ny--;
  276. months = LunarYear.FromYear(ny).Months;
  277. }
  278. return months[index - rest];
  279. }
  280. }
  281. }
  282. }