yambroskin

DateHelper

Sep 28th, 2018 (edited)
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.18 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. namespace Impeltech.Bank.Helpers
  5. {
  6. public static class DateHelper
  7. {
  8. #region Кварталы
  9. public static readonly List<LastQuartDay> QuartDays = new List<LastQuartDay>
  10. {
  11. new LastQuartDay(
  12. day: 31, month: 03),
  13. new LastQuartDay(
  14. day: 30, month: 06),
  15. new LastQuartDay(
  16. day: 30, month: 09),
  17. new LastQuartDay(
  18. day: 31, month: 12)
  19. };
  20. /// <summary>
  21. /// Возвращает
  22. /// </summary>
  23. /// <param name="quartNumber">номер квартала</param>
  24. /// <returns>LastQuartDay</returns>
  25. public static LastQuartDay Quart(int quartNumber)
  26. {
  27. return QuartDays[quartNumber - 1];
  28. }
  29. public class LastQuartDay
  30. {
  31. public LastQuartDay(int day, int month)
  32. {
  33. Month = month;
  34. Day = day;
  35. }
  36. public int Month { get; set; }
  37. public int Day { get; set; }
  38. }
  39. #endregion
  40. #region Крайние даты отчетности (на основе двух дат отчетности крайних, используется на портале)
  41. /// <summary>
  42. /// Крайняя годовая отчетность
  43. /// </summary>
  44. /// <returns></returns>
  45. public static DateTime DatesReportingYear()
  46. {
  47. return DatesReportingYear(DateTime.Now);
  48. }
  49. /// <summary>
  50. /// Крайняя годовая отчетность
  51. /// </summary>
  52. /// <param name="date"></param>
  53. /// <returns></returns>
  54. public static DateTime DatesReportingYear(this DateTime date)
  55. {
  56. DateTime year;
  57. DateTime last;
  58. DatesReportingRange(date, out year, out last);
  59. return year;
  60. }
  61. /// <summary>
  62. /// Крайняя дата отчетности
  63. /// </summary>
  64. /// <returns></returns>
  65. public static DateTime DatesReportingLast()
  66. {
  67. return DatesReportingLast(DateTime.Now);
  68. }
  69. /// <summary>
  70. /// Крайняя дата отчетности
  71. /// </summary>
  72. /// <param name="date"></param>
  73. /// <returns></returns>
  74. public static DateTime DatesReportingLast(this DateTime date)
  75. {
  76. DateTime year;
  77. DateTime last;
  78. DatesReportingRange(date, out year, out last);
  79. return last;
  80. }
  81. /// <summary>
  82. /// Минимальная дата для копирования
  83. /// </summary>
  84. /// <param name="date"></param>
  85. /// <returns></returns>
  86. public static DateTime MinDateCopy(this DateTime date)
  87. {
  88. return DatesReportingLast(date);
  89. }
  90. /// <summary>
  91. /// Минимальная дата для заявки на лимит
  92. /// </summary>
  93. /// <param name="date"></param>
  94. /// <returns></returns>
  95. public static DateTime MinDateRequestLimit(this DateTime date)
  96. {
  97. //два квартала
  98. return date.DatesReportingLast().DatesReportingLast();
  99. }
  100. #endregion
  101. #region Две даты отчетности
  102. /// <summary>
  103. /// Две отчетности
  104. /// </summary>
  105. /// <param name="date"></param>
  106. /// <param name="year"></param>
  107. /// <param name="last"></param>
  108. public static void DatesReportingRange(this DateTime date, out DateTime year, out DateTime last)
  109. {
  110. var oldDate = date;
  111. if (date.Month != 4)
  112. {
  113. date = date.AddMonths(-1);
  114. }
  115. last = GetPreviosDate(date);
  116. year = GetPreviosDateByYear(last);
  117. //если сейчас апрель
  118. if (oldDate.Month == 4)
  119. {
  120. //спрашиваем вместо квартальной ближайшую годовую
  121. last = year;
  122. // и спрашиваем минус год
  123. year = year.AddYears(-1);
  124. }
  125. else
  126. {
  127. //если квартал крайний совпадает с крайним годом то вызовем снова метод но для квартала (т.е. минус 1 квартал спрашиваем)
  128. if (last.Month == year.Month && year.Day == last.Day)
  129. {
  130. DatesReportingRange(last, out year, out last);
  131. }
  132. }
  133. }
  134. #region Ближайшие даты + -
  135. public static DateTime GetNextDate(this DateTime start)
  136. {
  137. return GetNextDate(start, DateTime.MaxValue);
  138. }
  139. /// <summary>
  140. /// Ближайшая дата начала
  141. /// </summary>
  142. /// <param name="start"></param>
  143. /// <param name="max"></param>
  144. /// <returns></returns>
  145. public static DateTime GetNextDate(this DateTime start, DateTime max)
  146. {
  147. var date = NextQuarts(start).FirstOrDefault();
  148. return date < max ? date : max.AddDays(1);
  149. }
  150. /// <summary>
  151. /// Ближайшую дату отчетности (в прошлом)
  152. /// </summary>
  153. /// <param name="start"></param>
  154. /// <returns></returns>
  155. public static DateTime GetPreviosDate(this DateTime start)
  156. {
  157. return GetLastQuarts(start).OrderByDescending(c => c).FirstOrDefault();
  158. }
  159. #endregion
  160. #endregion
  161. #region Получение кварталов
  162. /// <summary>
  163. /// Получит последние кварталы
  164. /// </summary>
  165. /// <returns></returns>
  166. public static List<DateTime> GetLastQuarts()
  167. {
  168. return GetLastQuarts(DateTime.Today);
  169. }
  170. /// <summary>
  171. /// Получит последние кварталы
  172. /// </summary>
  173. /// <returns></returns>
  174. public static List<DateTime> GetLastQuarts(this DateTime date)
  175. {
  176. var list = new List<DateTime>
  177. {
  178. PreviosQuartDate(date, 1),
  179. PreviosQuartDate(date, 2),
  180. PreviosQuartDate(date, 3),
  181. PreviosQuartDate(date, 4)
  182. };
  183. return list.OrderBy(c => c).ToList();
  184. }
  185. public static DateTime PreviosQuartDate(this DateTime date, int quartNumber)
  186. {
  187. return GetPreviosByYear(date, Quart(quartNumber));
  188. }
  189. public static List<DateTime> GetDatesByQuarts(List<int> quarts)
  190. {
  191. return GetDatesByQuarts(DateTime.Today, quarts);
  192. }
  193. public static List<DateTime> GetDatesByQuarts(this DateTime dateFrom, IEnumerable<int> quarts)
  194. {
  195. var list = new List<DateTime>();
  196. foreach (var quart in quarts)
  197. {
  198. DateTime prevDate;
  199. if (quart == 0)
  200. {
  201. prevDate = dateFrom.AddYears(-1);
  202. }
  203. else
  204. {
  205. prevDate = dateFrom.PreviosQuartDate(quart);
  206. list.Add(prevDate);
  207. }
  208. dateFrom = prevDate;
  209. }
  210. return list;
  211. }
  212. /// <summary>
  213. /// Получить следующие даты крайних кварталов кварталы
  214. /// </summary>
  215. /// <param name="date"></param>
  216. /// <returns></returns>
  217. public static IEnumerable<DateTime> NextQuarts(this DateTime date)
  218. {
  219. return new List<DateTime>
  220. {
  221. GetNextDateByYear(date, Quart(1)),
  222. GetNextDateByYear(date, Quart(2)),
  223. GetNextDateByYear(date, Quart(3)),
  224. GetNextDateByYear(date, Quart(4))
  225. }.OrderBy(c => c).ToList();
  226. }
  227. /// <summary>
  228. /// Получить номер квартала по крайней дате (работает только с датами крайними кварталов //31, 03//30, 06//30, 09//31, 12)
  229. /// </summary>
  230. /// <returns></returns>
  231. public static int GetQuartNumber(this DateTime date)
  232. {
  233. if (date.Month == 3 && date.Day == 31)
  234. {
  235. return 1;
  236. }
  237. if (date.Month == 6 && date.Day == 30)
  238. {
  239. return 2;
  240. }
  241. if (date.Month == 9 && date.Day == 30)
  242. {
  243. return 3;
  244. }
  245. if (date.Month == 12 && date.Day == 31)
  246. {
  247. return 4;
  248. }
  249. return 0;
  250. }
  251. #endregion
  252. #region Вернуть Даты отчетности по количеству дат
  253. public static IEnumerable<DateTime> GetReportingDates(int count)
  254. {
  255. return GetReportingDates(DateTime.Today, count);
  256. }
  257. public static IEnumerable<DateTime> GetReportingDates(this DateTime dateTime, int count)
  258. {
  259. var alwaysToAdd = new List<DateTime>();
  260. var quarts = new List<DateTime>();
  261. var years = new List<DateTime>();
  262. AddDates(quarts, years, alwaysToAdd, dateTime);
  263. //один кварттал отведем оставим как годовой
  264. while (quarts.Count < count - 1)
  265. {
  266. var lastQuart = quarts.OrderBy(c => c).FirstOrDefault();
  267. if (lastQuart == DateTime.MinValue)
  268. {
  269. // если попали сюда то значит должны вернуть 2 года обязательно т.к. крайний год теперь считаем за квартал
  270. lastQuart = years.OrderByDescending(c => c).FirstOrDefault();
  271. //добавим его к тем которые добавляем всегда
  272. var always = years.OrderByDescending(c => c).LastOrDefault();
  273. //если число кварталов больше значит нужна динамика и мы не добавляем дополнительнае года
  274. if (count < 3)
  275. {
  276. alwaysToAdd.Add(always);
  277. }
  278. years.Remove(always);
  279. }
  280. AddDates(quarts, years, alwaysToAdd, lastQuart);
  281. }
  282. //добавим года
  283. var yearsCount = quarts.Count / 3 + 1;
  284. quarts.AddRange(years.OrderByDescending(c => c).Take(yearsCount));
  285. if (alwaysToAdd.Count >= count)
  286. {
  287. return alwaysToAdd;
  288. }
  289. //количество кварталов которые надо взять
  290. var dif = count - alwaysToAdd.Count;
  291. var list = quarts.OrderByDescending(c => c).ToList().Take(dif).ToList();
  292. list.AddRange(alwaysToAdd);
  293. if (count != list.Count)
  294. {
  295. throw new Exception($"{count} != {list.Count}");
  296. }
  297. return list.OrderByDescending(c => c).ToList().Take(count);
  298. }
  299. private static void AddDates(ICollection<DateTime> quarts, ICollection<DateTime> years, ICollection<DateTime> alwaysToAdd, DateTime date)
  300. {
  301. DateTime from, to;
  302. DatesReportingRange(date, out from, out to);
  303. AddIfNotContains(from.Month == 12 ? years : quarts, alwaysToAdd, from);
  304. AddIfNotContains(to.Month == 12 ? years : quarts, alwaysToAdd, to);
  305. }
  306. private static void AddIfNotContains(ICollection<DateTime> list, ICollection<DateTime> alwaysToAdd, DateTime date)
  307. {
  308. if (!list.Contains(date) && !alwaysToAdd.Contains(date))
  309. {
  310. list.Add(date);
  311. }
  312. }
  313. #endregion
  314. #region Служебное
  315. /// <summary>
  316. /// Дата годовой отчетности для предыдущего года
  317. /// </summary>
  318. /// <param name="date"></param>
  319. /// <returns></returns>
  320. private static DateTime GetPreviosDateByYear(this DateTime date)
  321. {
  322. return new DateTime(date.Year - 1, 12, 31);
  323. }
  324. /// <summary>
  325. /// Ближайшая следующая дата
  326. /// </summary>
  327. /// <param name="date">От </param>
  328. /// <param name="lastQuartDay"></param>
  329. /// <returns></returns>
  330. private static DateTime GetNextDateByYear(this DateTime date, LastQuartDay lastQuartDay)
  331. {
  332. var nextDate = new DateTime(date.Year, lastQuartDay.Month, lastQuartDay.Day);
  333. return nextDate <= date ? nextDate.AddYears(1).AddDays(1) : nextDate.AddDays(1);
  334. }
  335. /// <summary>
  336. /// Ближайшая прошедшая дата
  337. /// </summary>
  338. /// <param name="date">От </param>
  339. /// <param name="lastQuartDay"></param>
  340. /// <returns></returns>
  341. private static DateTime GetPreviosByYear(this DateTime date, LastQuartDay lastQuartDay)
  342. {
  343. var curDate = new DateTime(date.Year, lastQuartDay.Month, lastQuartDay.Day);
  344. return date <= curDate ? curDate.AddYears(-1) : curDate;
  345. }
  346. /// <summary>
  347. /// Количество дней в году
  348. /// </summary>
  349. /// <param name="date"></param>
  350. /// <returns></returns>
  351. public static int GetDaysInYear(this DateTime date)
  352. {
  353. var start = new DateTime(date.Year, 1, 1);
  354. var end = start.AddYears(1);
  355. return (int)(end - start).TotalDays;
  356. }
  357. #endregion
  358. }
  359. }
Add Comment
Please, Sign In to add comment