在我的系统中,账单的到期日必须是开具日期后的 14 天。
我有截止日期,我想知道发布日期。
我必须计算:
issued date = 14 days prior to the due date
但 14 天必须是工作日,而不是节假日。
假期存储在像这样的表'tblHolidayMaster'中,
日期 说明
2012/05/13 母亲节
2012/06/02 星期六 2012/12/25
圣诞节
如何计算避开节假日的签发日期?
感谢大家的关注和回复。
在我的系统中,账单的到期日必须是开具日期后的 14 天。
我有截止日期,我想知道发布日期。
我必须计算:
issued date = 14 days prior to the due date
但 14 天必须是工作日,而不是节假日。
假期存储在像这样的表'tblHolidayMaster'中,
日期 说明
2012/05/13 母亲节
2012/06/02 星期六 2012/12/25
圣诞节
如何计算避开节假日的签发日期?
感谢大家的关注和回复。
我将使用如下函数(我使用的函数)计算日期
public static DateTime AddBusinessDays(DateTime date, int days)
{
if (days == 0) return date;
if (date.DayOfWeek == DayOfWeek.Saturday)
{
date = date.AddDays(2);
days -= 1;
}
else if (date.DayOfWeek == DayOfWeek.Sunday)
{
date = date.AddDays(1);
days -= 1;
}
date = date.AddDays(days / 5 * 7);
int extraDays = days % 5;
if ((int)date.DayOfWeek + extraDays > 5)
{
extraDays += 2;
}
int extraDaysForHolidays =-1;
//Load holidays from DB into list
List<DateTime> dates = GetHolidays();
while(extraDaysForHolidays !=0)
{
var days = dates.Where(x => x >= date && x <= date.AddDays(extraDays)).Count;
extraDaysForHolidays =days;
extraDays+=days;
}
return date.AddDays(extraDays);
}
没有测试过假期的 ast 部分
我采用了直接循环解决方案,因此长时间间隔会很慢。但是对于像 14 天这样的短时间间隔,它应该是相当快的。
您需要在构造函数中传递假期。的实例BusinessDays
是不可变的,可以重用。在实践中,您可能会使用 IoC 单例或类似的构造来获取它。
AddBusinessDays
如果开始日期是非工作日,则抛出一个ArgumentException
,因为您没有指定如何处理这种情况。特别是AddBusinessDays(0)
在非工作日会有奇怪的属性,否则。它要么打破时间反转对称性,要么返回非工作日。
public class BusinessDays
{
private HashSet<DateTime> holidaySet;
public ReadOnlyCollection<DayOfWeek> WeekendDays{get; private set;}
public BusinessDays(IEnumerable<DateTime> holidays, IEnumerable<DayOfWeek> weekendDays)
{
WeekendDays = new ReadOnlyCollection<DayOfWeek>(weekendDays.Distinct().OrderBy(x=>x).ToArray());
if(holidays.Any(d => d != d.Date))
throw new ArgumentException("holidays", "A date must have time set to midnight");
holidaySet = new HashSet<DateTime>(holidays);
}
public BusinessDays(IEnumerable<DateTime> holidays)
:this(holidays, new[]{DayOfWeek.Saturday, DayOfWeek.Sunday})
{
}
public bool IsWeekend(DayOfWeek dayOfWeek)
{
return WeekendDays.Contains(dayOfWeek);
}
public bool IsWeekend(DateTime date)
{
return IsWeekend(date.DayOfWeek);
}
public bool IsHoliday(DateTime date)
{
return holidaySet.Contains(date.Date);
}
public bool IsBusinessDay(DateTime date)
{
return !IsWeekend(date) && !IsHoliday(date);
}
public DateTime AddBusinessDays(DateTime date, int days)
{
if(!IsBusinessDay(date))
throw new ArgumentException("date", "date bust be a business day");
int sign = Math.Sign(days);
while(days != 0)
{
do
{
date.AddDays(sign);
} while(!IsBusinessDay(date));
days -= sign;
}
return date;
}
}
我仅从您的表“tblHolidayMaster”计算发布日期避免您的假期。
int addDay = -14;
DateTime dtInputDay = System.DateTime.Now;//Your input day
DateTime dtResultDate = new DateTime();
dtResultDate = dtInputDay.AddDays(addDay);
bool result = false;
string strExpression;
DataView haveHoliday;
while (!result) {
strExpression = "Date >='" + Convert.ToDateTime(dtResultDate.ToString("yyyy/MM/dd")) + "' and Date <='" + Convert.ToDateTime(dtInputDay.ToString("yyyy/MM/dd")) + "'";
haveHoliday = new DataView(tblHolidayMaster);
haveHoliday.RowFilter = strExpression;
if (haveHoliday.Count == 0) {
result = true;
} else {
addDay = -(haveHoliday.Count);
dtInputDay = dtResultDate.AddDays(-1);
dtResultDate = dtResultDate.AddDays(addDay);
}
}
您的签发日期是 dtResultDate
我认为这就是你所需要的。它很简单,我已经对其进行了测试,它正在工作......在数据库中编写函数或 SP 而不是在 C# 中编写复杂代码......(更改日期的列名,如您的D b。)
让它发挥你想要的功能或 SP。
注意:注释“星期六”和“星期日”的检查。如果它已经添加到您的表记录中。
declare @NextWorkingDate datetime
declare @CurrentDate datetime
set @CurrentDate = GETDATE()
set @NextWorkingDate = @CurrentDate
declare @i int = 0
While(@i < 14)
Begin
if(((select COUNT(*) from dbo.tblHolidayMaster where convert(varchar(10),[Date],101) like convert(varchar(10),@NextWorkingDate,101)) > 0) OR DATENAME(WEEKDAY,@NextWorkingDate) = 'Saturday' OR DATENAME(WEEKDAY,@NextWorkingDate) = 'Sunday')
Begin
print 'a '
print @NextWorkingDate
set @NextWorkingDate = @NextWorkingDate + 1
CONTINUE
End
else
Begin
print 'b '
print @NextWorkingDate
set @NextWorkingDate = @NextWorkingDate + 1
set @i = @i + 1
CONTINUE
End
End
print @NextWorkingDate
试试下面的链接,
http://www.c-sharpcorner.com/uploadfile/tirthacs/difference-between-two-dates- exclude-weekends/