using System; using System.Globalization; namespace AntDesign { public static class DateHelper { private static readonly System.Globalization.Calendar _calendar = CultureInfo.InvariantCulture.Calendar; private const int DECADE_YEAR_COUNT = 10; private const int QUARTER_MONTH_COUNT = 3; public static bool IsSameDate(DateTime date, DateTime compareDate) { return date == compareDate; } public static bool IsSameYear(DateTime date, DateTime compareDate) { return date.Year == compareDate.Year; } public static bool IsSameMonth(DateTime date, DateTime compareDate) { return IsSameYear(date, compareDate) && date.Month == compareDate.Month; } public static bool IsSameDay(DateTime date, DateTime compareDate) { return IsSameYear(date, compareDate) && _calendar.GetDayOfYear(date) == _calendar.GetDayOfYear(compareDate); } public static bool IsSameWeak(DateTime date, DateTime compareDate) { return IsSameYear(date, compareDate) && GetWeekOfYear(date) == GetWeekOfYear(compareDate); } public static bool IsSameQuarter(DateTime date, DateTime compareDate) { return IsSameYear(date, compareDate) && GetDayOfQuarter(date) == GetDayOfQuarter(compareDate); } public static string GetDayOfQuarter(DateTime date) { return $"Q{GetQuarter(date)}"; } public static int GetQuarter(DateTime date) { int offset = date.Month % QUARTER_MONTH_COUNT > 0 ? 1 : 0; int quarter = date.Month / QUARTER_MONTH_COUNT + offset; return quarter; } public static DateTime GetStartDateOfQuarter(DateTime date) { int quarter = GetQuarter(date); return new DateTime(date.Year, 1 + ((quarter - 1) * QUARTER_MONTH_COUNT), 1); } public static int GetWeekOfYear(DateTime date) { return _calendar.GetWeekOfYear(date, CalendarWeekRule.FirstDay, DayOfWeek.Monday); } /// /// for example, /// when currentDateTime is 2020-01-04 05:34:55 then: /// the next date shouble be 2030-01-01 00:00:00, it's the start date of next 10 years /// /// when currentDateTime is 2023-01-04 05:34:55 then: /// the next date shouble be 2030-01-01 00:00:00, it's the start date of next 10 years /// /// when currentDateTime is 2018-01-04 05:34:55 then: /// the next date shouble be 2020-01-01 00:00:00, it's the start date of next 10 years /// /// /// public static DateTime GetNextStartDateOfDecade(DateTime date) { int year = date.Year / DECADE_YEAR_COUNT * DECADE_YEAR_COUNT; if (year < DateTime.MinValue.Year) { year = DateTime.MinValue.Year; } return AddYearsSafely(new DateTime(year, 1, 1), DECADE_YEAR_COUNT); } /// /// for example, when currentDateTime is 2020-01-04 05:34:55 then: /// the next date shouble be 2021-01-01 00:00:00, it's the start date of next year /// /// /// public static DateTime GetNextStartDateOfYear(DateTime date) { return AddYearsSafely(new DateTime(date.Year, 1, 1), 1); } /// /// for example, when currentDateTime is 2020-01-04 05:34:55 then: /// the next date shouble be 2020-04-01 00:00:00, it's the start date of the next quarter in 2020 /// /// /// public static DateTime GetNextStartDateOfQuarter(DateTime date) { var nextQuarterDate = AddMonthsSafely(new DateTime(date.Year, date.Month, 1), QUARTER_MONTH_COUNT); return GetStartDateOfQuarter(nextQuarterDate); } /// /// for example, when currentDateTime is 2020-01-04 05:34:55 then: /// the next date shouble be 2020-02-01 00:00:00 , it's the start date of next month /// /// /// public static DateTime GetNextStartDateOfMonth(DateTime date) { return AddMonthsSafely(new DateTime(date.Year, date.Month, 1), 1); } /// /// for example, when currentDateTime is 2020-01-04 05:34:55 then: /// the next date shouble be 2021-01-05 00:00:00, it's the start date of next day /// /// /// public static DateTime GetNextStartDateOfDay(DateTime date) { return AddDaysSafely(new DateTime(date.Year, date.Month, date.Day), 1); } public static DateTime CombineNewDate( DateTime date, int? year = null, int? month = null, int? day = null, int? hour = null, int? minute = null, int? second = null) { return date .AddYears(year != null ? (int)year - date.Year : 0) .AddMonths(month != null ? (int)month - date.Month : 0) .AddDays(day != null ? (int)day - date.Day : 0) .AddHours(hour != null ? (int)hour - date.Hour : 0) .AddMinutes(minute != null ? (int)minute - date.Minute : 0) .AddSeconds(second != null ? (int)second - date.Second : 0); } public static DateTime? FormatDateByPicker(DateTime? dateTime, string picker) { if (dateTime == null) { return null; } return FormatDateByPicker((DateTime)dateTime, picker); } public static DateTime FormatDateByPicker(DateTime dateTime, string picker) { switch (picker) { case DatePickerType.Date: return dateTime.Date; case DatePickerType.Year: return new DateTime(dateTime.Year, 1, 1); case DatePickerType.Month: return new DateTime(dateTime.Year, dateTime.Month, 1); case DatePickerType.Quarter: return new DateTime(dateTime.Year, dateTime.Month, 1); } return dateTime; } /// /// 用该函数来执行AddYears逻辑, 不会触发System.ArgumentOutOfRangeException异常 /// AddYears by the function would never throw System.ArgumentOutOfRangeException /// /// /// /// public static DateTime AddYearsSafely(DateTime currentDate, int value) { int newYear = currentDate.Year + value; if (newYear < DateTime.MinValue.Year) { value = DateTime.MinValue.Year - currentDate.Year; } else if (newYear > DateTime.MaxValue.Year) { value = DateTime.MaxValue.Year - currentDate.Year; } return currentDate.AddYears(value); } /// /// 用该函数来执行AddMonths逻辑, 不会触发System.ArgumentOutOfRangeException异常 /// AddMonths by the function would never throw System.ArgumentOutOfRangeException /// /// /// /// public static DateTime AddMonthsSafely(DateTime currentDate, int value) { int newMonth = currentDate.Month + value; /* at min date value */ if (currentDate.Year == DateTime.MinValue.Year && newMonth < DateTime.MinValue.Month) { value = DateTime.MinValue.Month - currentDate.Month; } /* at max date value */ if (currentDate.Year == DateTime.MaxValue.Year && newMonth > DateTime.MaxValue.Month) { value = DateTime.MaxValue.Month - currentDate.Month; } return currentDate.AddMonths(value); } /// /// 用该函数来执行AddDays逻辑, 不会触发System.ArgumentOutOfRangeException异常 /// AddDays by the function would never throw System.ArgumentOutOfRangeException /// /// /// /// public static DateTime AddDaysSafely(DateTime currentDate, int value) { int newDay = currentDate.Day + value; /* at min date value */ if (currentDate.Year == DateTime.MinValue.Year && currentDate.Month == DateTime.MinValue.Month && newDay < DateTime.MinValue.Day) { value = DateTime.MinValue.Day - currentDate.Day; } /* at max date value */ if (currentDate.Year == DateTime.MaxValue.Year && currentDate.Month == DateTime.MaxValue.Month && newDay > DateTime.MaxValue.Day) { value = DateTime.MaxValue.Day - currentDate.Day; } return currentDate.AddDays(value); } } }