Keine Beschreibung
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

SolarWeek.cs 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Lunar.Util;
  5. // ReSharper disable MemberCanBePrivate.Global
  6. namespace Lunar
  7. {
  8. /// <summary>
  9. /// 阳历周
  10. /// </summary>
  11. public class SolarWeek
  12. {
  13. /// <summary>
  14. /// 年
  15. /// </summary>
  16. public int Year { get; }
  17. /// <summary>
  18. /// 月
  19. /// </summary>
  20. public int Month { get; }
  21. /// <summary>
  22. /// 日
  23. /// </summary>
  24. public int Day { get; }
  25. /// <summary>
  26. /// 星期几作为一周的开始,1234560分别代表星期一至星期天
  27. /// </summary>
  28. public int Start { get; }
  29. /// <summary>
  30. /// 默认当月
  31. /// </summary>
  32. /// <param name="start">星期几作为一周的开始,1234560分别代表星期一至星期天</param>
  33. public SolarWeek(int start): this(DateTime.Now, start)
  34. {
  35. }
  36. /// <summary>
  37. /// 通过日期初始化
  38. /// </summary>
  39. /// <param name="date">日期</param>
  40. /// <param name="start">星期几作为一周的开始,1234560分别代表星期一至星期天</param>
  41. public SolarWeek(DateTime date, int start):this(date.Year, date.Month, date.Day, start)
  42. {
  43. }
  44. /// <summary>
  45. /// 通过年月初始化
  46. /// </summary>
  47. /// <param name="year">年</param>
  48. /// <param name="month">月,1到12</param>
  49. /// <param name="day">日,1到31</param>
  50. /// <param name="start">星期几作为一周的开始,1234560分别代表星期一至星期天</param>
  51. public SolarWeek(int year, int month, int day, int start)
  52. {
  53. Year = year;
  54. Month = month;
  55. Day = day;
  56. Start = start;
  57. }
  58. /// <summary>
  59. /// 通过指定日期获取阳历周
  60. /// </summary>
  61. /// <param name="date">日期</param>
  62. /// <param name="start">星期几作为一周的开始,1234560分别代表星期一至星期天</param>
  63. /// <returns>阳历周</returns>
  64. public static SolarWeek FromDate(DateTime date, int start)
  65. {
  66. return new SolarWeek(date, start);
  67. }
  68. /// <summary>
  69. /// 通过指定年月日获取阳历周
  70. /// </summary>
  71. /// <param name="year">年</param>
  72. /// <param name="month">月,1到12</param>
  73. /// <param name="day">日,1到31</param>
  74. /// <param name="start">星期几作为一周的开始,1234560分别代表星期一至星期天</param>
  75. /// <returns>阳历周</returns>
  76. public static SolarWeek FromYmd(int year, int month, int day, int start)
  77. {
  78. return new SolarWeek(year, month, day, start);
  79. }
  80. /// <summary>
  81. /// 当前日期是在当月第几周,从1开始
  82. /// </summary>
  83. public int Index
  84. {
  85. get
  86. {
  87. var offset = Solar.FromYmdHms(Year, Month, 1).Week - Start;
  88. if (offset < 0)
  89. {
  90. offset += 7;
  91. }
  92. return (int)Math.Ceiling((Day + offset) * 1D / 7);
  93. }
  94. }
  95. /// <summary>
  96. /// 当前日期是在当年第几周,从1开始
  97. /// </summary>
  98. public int IndexInYear
  99. {
  100. get
  101. {
  102. var offset = Solar.FromYmdHms(Year, 1, 1).Week - Start;
  103. if (offset < 0)
  104. {
  105. offset += 7;
  106. }
  107. return (int) Math.Ceiling((SolarUtil.GetDaysInYear(Year, Month, Day) + offset) * 1D / 7);
  108. }
  109. }
  110. /// <summary>
  111. /// 周推移
  112. /// </summary>
  113. /// <param name="weeks">推移的周数,负数为倒推</param>
  114. /// <param name="separateMonth">是否按月单独计算</param>
  115. /// <returns>推移后的阳历周</returns>
  116. public SolarWeek Next(int weeks, bool separateMonth)
  117. {
  118. if (0 == weeks)
  119. {
  120. return new SolarWeek(Year, Month, Day, Start);
  121. }
  122. var solar = Solar.FromYmdHms(Year, Month, Day);
  123. if (separateMonth)
  124. {
  125. var n = weeks;
  126. var week = new SolarWeek(solar.Year, solar.Month, solar.Day, Start);
  127. var m = Month;
  128. var plus = n > 0;
  129. while (0 != n)
  130. {
  131. solar = solar.Next(plus ? 7 : -7);
  132. week = new SolarWeek(solar.Year, solar.Month, solar.Day, Start);
  133. var weekMonth = week.Month;
  134. if (m != weekMonth)
  135. {
  136. var index = week.Index;
  137. if (plus)
  138. {
  139. if (1 == index)
  140. {
  141. var firstDay = week.FirstDay;
  142. week = new SolarWeek(firstDay.Year, firstDay.Month, firstDay.Day, Start);
  143. weekMonth = week.Month;
  144. }
  145. else
  146. {
  147. solar = Solar.FromYmdHms(week.Year, week.Month, 1);
  148. week = new SolarWeek(solar.Year, solar.Month, solar.Day, Start);
  149. }
  150. }
  151. else
  152. {
  153. if (SolarUtil.GetWeeksOfMonth(week.Year, week.Month, Start) == index)
  154. {
  155. var lastDay = week.FirstDay.Next(6);
  156. week = new SolarWeek(lastDay.Year, lastDay.Month, lastDay.Day, Start);
  157. weekMonth = week.Month;
  158. }
  159. else
  160. {
  161. solar = Solar.FromYmdHms(week.Year, week.Month, SolarUtil.GetDaysOfMonth(week.Year, week.Month));
  162. week = new SolarWeek(solar.Year, solar.Month, solar.Day, Start);
  163. }
  164. }
  165. m = weekMonth;
  166. }
  167. n -= plus ? 1 : -1;
  168. }
  169. return week;
  170. }
  171. else
  172. {
  173. solar = solar.Next(weeks * 7);
  174. return new SolarWeek(solar.Year, solar.Month, solar.Day, Start);
  175. }
  176. }
  177. /// <summary>
  178. /// 本周第一天的阳历日期(可能跨月)
  179. /// </summary>
  180. public Solar FirstDay
  181. {
  182. get
  183. {
  184. var solar = Solar.FromYmdHms(Year, Month, Day);
  185. var prev = solar.Week - Start;
  186. if (prev < 0)
  187. {
  188. prev += 7;
  189. }
  190. return solar.Next(-prev);
  191. }
  192. }
  193. /// <summary>
  194. /// 本周第一天的阳历日期(仅限当月)
  195. /// </summary>
  196. public Solar FirstDayInMonth
  197. {
  198. get
  199. {
  200. return Days.FirstOrDefault(day => Month == day.Month);
  201. }
  202. }
  203. /// <summary>
  204. /// 本周的阳历日期列表(可能跨月)
  205. /// </summary>
  206. public List<Solar> Days
  207. {
  208. get
  209. {
  210. var firstDay = FirstDay;
  211. var l = new List<Solar> {firstDay};
  212. for (var i = 1; i < 7; i++)
  213. {
  214. l.Add(firstDay.Next(i));
  215. }
  216. return l;
  217. }
  218. }
  219. /// <summary>
  220. /// 本周的阳历日期列表(仅限当月)
  221. /// </summary>
  222. public List<Solar> DaysInMonth
  223. {
  224. get
  225. {
  226. return Days.Where(day => Month == day.Month).ToList();
  227. }
  228. }
  229. /// <inheritdoc />
  230. public override string ToString()
  231. {
  232. return Year + "." + Month + "." + Index;
  233. }
  234. /// <summary>
  235. /// 完整字符串输出
  236. /// </summary>
  237. public string FullString => Year + "年" + Month + "月第" + Index + "周";
  238. }
  239. }