Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- namespace Impeltech.Bank.Helpers
- {
- public static class DateHelper
- {
- #region Кварталы
- public static readonly List<LastQuartDay> QuartDays = new List<LastQuartDay>
- {
- new LastQuartDay(
- day: 31, month: 03),
- new LastQuartDay(
- day: 30, month: 06),
- new LastQuartDay(
- day: 30, month: 09),
- new LastQuartDay(
- day: 31, month: 12)
- };
- /// <summary>
- /// Возвращает
- /// </summary>
- /// <param name="quartNumber">номер квартала</param>
- /// <returns>LastQuartDay</returns>
- public static LastQuartDay Quart(int quartNumber)
- {
- return QuartDays[quartNumber - 1];
- }
- public class LastQuartDay
- {
- public LastQuartDay(int day, int month)
- {
- Month = month;
- Day = day;
- }
- public int Month { get; set; }
- public int Day { get; set; }
- }
- #endregion
- #region Крайние даты отчетности (на основе двух дат отчетности крайних, используется на портале)
- /// <summary>
- /// Крайняя годовая отчетность
- /// </summary>
- /// <returns></returns>
- public static DateTime DatesReportingYear()
- {
- return DatesReportingYear(DateTime.Now);
- }
- /// <summary>
- /// Крайняя годовая отчетность
- /// </summary>
- /// <param name="date"></param>
- /// <returns></returns>
- public static DateTime DatesReportingYear(this DateTime date)
- {
- DateTime year;
- DateTime last;
- DatesReportingRange(date, out year, out last);
- return year;
- }
- /// <summary>
- /// Крайняя дата отчетности
- /// </summary>
- /// <returns></returns>
- public static DateTime DatesReportingLast()
- {
- return DatesReportingLast(DateTime.Now);
- }
- /// <summary>
- /// Крайняя дата отчетности
- /// </summary>
- /// <param name="date"></param>
- /// <returns></returns>
- public static DateTime DatesReportingLast(this DateTime date)
- {
- DateTime year;
- DateTime last;
- DatesReportingRange(date, out year, out last);
- return last;
- }
- /// <summary>
- /// Минимальная дата для копирования
- /// </summary>
- /// <param name="date"></param>
- /// <returns></returns>
- public static DateTime MinDateCopy(this DateTime date)
- {
- return DatesReportingLast(date);
- }
- /// <summary>
- /// Минимальная дата для заявки на лимит
- /// </summary>
- /// <param name="date"></param>
- /// <returns></returns>
- public static DateTime MinDateRequestLimit(this DateTime date)
- {
- //два квартала
- return date.DatesReportingLast().DatesReportingLast();
- }
- #endregion
- #region Две даты отчетности
- /// <summary>
- /// Две отчетности
- /// </summary>
- /// <param name="date"></param>
- /// <param name="year"></param>
- /// <param name="last"></param>
- public static void DatesReportingRange(this DateTime date, out DateTime year, out DateTime last)
- {
- var oldDate = date;
- if (date.Month != 4)
- {
- date = date.AddMonths(-1);
- }
- last = GetPreviosDate(date);
- year = GetPreviosDateByYear(last);
- //если сейчас апрель
- if (oldDate.Month == 4)
- {
- //спрашиваем вместо квартальной ближайшую годовую
- last = year;
- // и спрашиваем минус год
- year = year.AddYears(-1);
- }
- else
- {
- //если квартал крайний совпадает с крайним годом то вызовем снова метод но для квартала (т.е. минус 1 квартал спрашиваем)
- if (last.Month == year.Month && year.Day == last.Day)
- {
- DatesReportingRange(last, out year, out last);
- }
- }
- }
- #region Ближайшие даты + -
- public static DateTime GetNextDate(this DateTime start)
- {
- return GetNextDate(start, DateTime.MaxValue);
- }
- /// <summary>
- /// Ближайшая дата начала
- /// </summary>
- /// <param name="start"></param>
- /// <param name="max"></param>
- /// <returns></returns>
- public static DateTime GetNextDate(this DateTime start, DateTime max)
- {
- var date = NextQuarts(start).FirstOrDefault();
- return date < max ? date : max.AddDays(1);
- }
- /// <summary>
- /// Ближайшую дату отчетности (в прошлом)
- /// </summary>
- /// <param name="start"></param>
- /// <returns></returns>
- public static DateTime GetPreviosDate(this DateTime start)
- {
- return GetLastQuarts(start).OrderByDescending(c => c).FirstOrDefault();
- }
- #endregion
- #endregion
- #region Получение кварталов
- /// <summary>
- /// Получит последние кварталы
- /// </summary>
- /// <returns></returns>
- public static List<DateTime> GetLastQuarts()
- {
- return GetLastQuarts(DateTime.Today);
- }
- /// <summary>
- /// Получит последние кварталы
- /// </summary>
- /// <returns></returns>
- public static List<DateTime> GetLastQuarts(this DateTime date)
- {
- var list = new List<DateTime>
- {
- PreviosQuartDate(date, 1),
- PreviosQuartDate(date, 2),
- PreviosQuartDate(date, 3),
- PreviosQuartDate(date, 4)
- };
- return list.OrderBy(c => c).ToList();
- }
- public static DateTime PreviosQuartDate(this DateTime date, int quartNumber)
- {
- return GetPreviosByYear(date, Quart(quartNumber));
- }
- public static List<DateTime> GetDatesByQuarts(List<int> quarts)
- {
- return GetDatesByQuarts(DateTime.Today, quarts);
- }
- public static List<DateTime> GetDatesByQuarts(this DateTime dateFrom, IEnumerable<int> quarts)
- {
- var list = new List<DateTime>();
- foreach (var quart in quarts)
- {
- DateTime prevDate;
- if (quart == 0)
- {
- prevDate = dateFrom.AddYears(-1);
- }
- else
- {
- prevDate = dateFrom.PreviosQuartDate(quart);
- list.Add(prevDate);
- }
- dateFrom = prevDate;
- }
- return list;
- }
- /// <summary>
- /// Получить следующие даты крайних кварталов кварталы
- /// </summary>
- /// <param name="date"></param>
- /// <returns></returns>
- public static IEnumerable<DateTime> NextQuarts(this DateTime date)
- {
- return new List<DateTime>
- {
- GetNextDateByYear(date, Quart(1)),
- GetNextDateByYear(date, Quart(2)),
- GetNextDateByYear(date, Quart(3)),
- GetNextDateByYear(date, Quart(4))
- }.OrderBy(c => c).ToList();
- }
- /// <summary>
- /// Получить номер квартала по крайней дате (работает только с датами крайними кварталов //31, 03//30, 06//30, 09//31, 12)
- /// </summary>
- /// <returns></returns>
- public static int GetQuartNumber(this DateTime date)
- {
- if (date.Month == 3 && date.Day == 31)
- {
- return 1;
- }
- if (date.Month == 6 && date.Day == 30)
- {
- return 2;
- }
- if (date.Month == 9 && date.Day == 30)
- {
- return 3;
- }
- if (date.Month == 12 && date.Day == 31)
- {
- return 4;
- }
- return 0;
- }
- #endregion
- #region Вернуть Даты отчетности по количеству дат
- public static IEnumerable<DateTime> GetReportingDates(int count)
- {
- return GetReportingDates(DateTime.Today, count);
- }
- public static IEnumerable<DateTime> GetReportingDates(this DateTime dateTime, int count)
- {
- var alwaysToAdd = new List<DateTime>();
- var quarts = new List<DateTime>();
- var years = new List<DateTime>();
- AddDates(quarts, years, alwaysToAdd, dateTime);
- //один кварттал отведем оставим как годовой
- while (quarts.Count < count - 1)
- {
- var lastQuart = quarts.OrderBy(c => c).FirstOrDefault();
- if (lastQuart == DateTime.MinValue)
- {
- // если попали сюда то значит должны вернуть 2 года обязательно т.к. крайний год теперь считаем за квартал
- lastQuart = years.OrderByDescending(c => c).FirstOrDefault();
- //добавим его к тем которые добавляем всегда
- var always = years.OrderByDescending(c => c).LastOrDefault();
- //если число кварталов больше значит нужна динамика и мы не добавляем дополнительнае года
- if (count < 3)
- {
- alwaysToAdd.Add(always);
- }
- years.Remove(always);
- }
- AddDates(quarts, years, alwaysToAdd, lastQuart);
- }
- //добавим года
- var yearsCount = quarts.Count / 3 + 1;
- quarts.AddRange(years.OrderByDescending(c => c).Take(yearsCount));
- if (alwaysToAdd.Count >= count)
- {
- return alwaysToAdd;
- }
- //количество кварталов которые надо взять
- var dif = count - alwaysToAdd.Count;
- var list = quarts.OrderByDescending(c => c).ToList().Take(dif).ToList();
- list.AddRange(alwaysToAdd);
- if (count != list.Count)
- {
- throw new Exception($"{count} != {list.Count}");
- }
- return list.OrderByDescending(c => c).ToList().Take(count);
- }
- private static void AddDates(ICollection<DateTime> quarts, ICollection<DateTime> years, ICollection<DateTime> alwaysToAdd, DateTime date)
- {
- DateTime from, to;
- DatesReportingRange(date, out from, out to);
- AddIfNotContains(from.Month == 12 ? years : quarts, alwaysToAdd, from);
- AddIfNotContains(to.Month == 12 ? years : quarts, alwaysToAdd, to);
- }
- private static void AddIfNotContains(ICollection<DateTime> list, ICollection<DateTime> alwaysToAdd, DateTime date)
- {
- if (!list.Contains(date) && !alwaysToAdd.Contains(date))
- {
- list.Add(date);
- }
- }
- #endregion
- #region Служебное
- /// <summary>
- /// Дата годовой отчетности для предыдущего года
- /// </summary>
- /// <param name="date"></param>
- /// <returns></returns>
- private static DateTime GetPreviosDateByYear(this DateTime date)
- {
- return new DateTime(date.Year - 1, 12, 31);
- }
- /// <summary>
- /// Ближайшая следующая дата
- /// </summary>
- /// <param name="date">От </param>
- /// <param name="lastQuartDay"></param>
- /// <returns></returns>
- private static DateTime GetNextDateByYear(this DateTime date, LastQuartDay lastQuartDay)
- {
- var nextDate = new DateTime(date.Year, lastQuartDay.Month, lastQuartDay.Day);
- return nextDate <= date ? nextDate.AddYears(1).AddDays(1) : nextDate.AddDays(1);
- }
- /// <summary>
- /// Ближайшая прошедшая дата
- /// </summary>
- /// <param name="date">От </param>
- /// <param name="lastQuartDay"></param>
- /// <returns></returns>
- private static DateTime GetPreviosByYear(this DateTime date, LastQuartDay lastQuartDay)
- {
- var curDate = new DateTime(date.Year, lastQuartDay.Month, lastQuartDay.Day);
- return date <= curDate ? curDate.AddYears(-1) : curDate;
- }
- /// <summary>
- /// Количество дней в году
- /// </summary>
- /// <param name="date"></param>
- /// <returns></returns>
- public static int GetDaysInYear(this DateTime date)
- {
- var start = new DateTime(date.Year, 1, 1);
- var end = start.AddYears(1);
- return (int)(end - start).TotalDays;
- }
- #endregion
- }
- }
Add Comment
Please, Sign In to add comment