如何在跳过周末和其他假日的情况下为日期添加天数
本文关键字:情况下 日期 添加 假日 其他 周末 | 更新日期: 2023-09-27 18:18:59
给定日期。我如何添加天数,而跳过周末和其他假期之间的范围?
List <DateTime> holidays = new List<DateTime>()
{
new DateTime(2012, 01, 03),
new DateTime(2012, 01, 26)
};
dateTimeReview.Value = CalculateFutureDate(dateTimeStart.Value, 7,holidays);
static DateTime CalculateFutureDate(DateTime fromDate, int numberofWorkDays, ICollection<DateTime> holidays)
{
var futureDate = fromDate;
for (var i = 0; i < numberofWorkDays; i++ )
{
if (futureDate.DayOfWeek == DayOfWeek.Saturday
|| futureDate.DayOfWeek == DayOfWeek.Sunday
|| (holidays != null && holidays.Contains(futureDate)))
{
futureDate = futureDate.AddDays(1); // Increase FutureDate by one because of condition
futureDate = futureDate.AddDays(1); // Add a working day
}
}
return futureDate;
}
要跳过假期,首先需要创建自己的假期列表。每个国家的假期都不一样,而且还受其他因素的影响。
然后,您应该在循环中逐个添加天数,并检查添加的天数是否不是周末,是否出现在假日列表中,直到添加给定的天数为止。
我尝试了上面的代码,但没有工作。返回的日期将以某种方式包括假日和周末。我还想检查返回的日期是否仅在工作日。
所以,下面是我修改的代码。
基本上,它将计算要添加的工作日数,如果结束日期是假日/周末,则将日期移到第二天。
请注意,这是在假设开始日期不是周末/节假日的情况下。
static DateTime CalculateFutureDate(DateTime fromDate, int numberofWorkDays,
ICollection<DateTime> holidays)
{
var futureDate = fromDate;
for (var i = 0; i < numberofWorkDays; i++ )
{
if (futureDate.DayOfWeek == DayOfWeek.Saturday
|| futureDate.DayOfWeek == DayOfWeek.Sunday
|| (holidays != null && holidays.Contains(futureDate)))
{
futureDate = futureDate.AddDays(1);
numberofWorkDays++;
}
else
{
futureDate = futureDate.AddDays(1);
}
}
while(futureDate.DayOfWeek == DayOfWeek.Saturday
|| futureDate.DayOfWeek == DayOfWeek.Sunday
|| (holidays != null && holidays.Contains(futureDate)))
{
futureDate = futureDate.AddDays(1);
}
return futureDate;
}
我已经构建了一个类似的东西来检查办公时间:
public static DateTime AddBusinessHours(DateTime date, long hours)
{
int i = 0;
DateTime tmpDate = date;
do
{
tmpDate = tmpDate.AddHours(1);
if (!IsWeekend(tmpDate) && !IsHoliday(tmpDate) && IsOfficeHours(tmpDate))
i++;
}
while (i < hours);
return tmpDate;
}
public static bool IsWeekend(DateTime date)
{
return (date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday);
}
public static bool IsHoliday(DateTime date)
{
//All dates in the holiday calendar are without hours and minutes.
//With the normal date object, the Contains does not work.
DateTime tmp = new DateTime(date.Year, date.Month, date.Day);
HolidayCalendar calendar = HolidayCalendar.Instance;
return (calendar.Dates.Contains(tmp));
}
public static bool IsOfficeHours(DateTime date)
{
return (date.Hour >= 8 && date.Hour < 20); //Office Hours are between 8AM and 8PM
}
但是正如上面提到的,你需要运行你自己的节日日历。
public static DateTime AddBusinessDays(DateTime pActualDate, int pNumberofWorkDays)
{
ICollection<DateTime> holidays = GetAllHolidays();
int i = default(int);
while (i < pNumberofWorkDays)
{
pActualDate = pActualDate.AddDays(1);
if (pActualDate.DayOfWeek == DayOfWeek.Saturday || pActualDate.DayOfWeek == DayOfWeek.Sunday
|| (holidays != null && holidays.Contains(pActualDate))) { }
else
{ i++; }
}
return pActualDate;
}
private static ICollection<DateTime> GetAllHolidays()
{
ICollection<DateTime> holidays = GetPublicHolidays().Select(s => s.Holidays).ToList();
HashSet<DateTime> finalHolidays = new HashSet<DateTime>();
//if sunday holiday then the following monday will be holiday
bool isMonday = GetCalendar().Any(s => s.Type == "KR" && s.IsMonday);
foreach (var hol in holidays)
{
if (hol.DayOfWeek == DayOfWeek.Sunday && isMonday)
{
//adding monday following day holiday to the list
finalHolidays.Add(hol.AddDays(1));
}
}
//exclude weekends from the holiday list
var excludeWeekends = holidays.Where(s => s.DayOfWeek == DayOfWeek.Sunday || s.DayOfWeek == DayOfWeek.Saturday);
//adding monday to the existing holiday collection
finalHolidays.UnionWith(holidays.Except(excludeWeekends));
return finalHolidays;
}