计算日期添加,但仅限工作日

时间:2009-10-14 23:00:11

标签: vb.net date

我想简单地使用内置dateadd函数计算一个新日期,但要考虑到只计算工作日(或“工作日”)。

我已经提出了这个简单的算法,它不会对假期等感到烦恼。我已经用一些简单的日期对它进行了测试,但是如果能以更好的方式完成,我想要一些输入。

此示例假定一周有一个工作日,周一至周五为5个工作日,其中一周的第一天是星期一。这里使用的日期格式是d-m-yyyy,样本以2009年10月1日的开始日期计算。

这是一个简单的表格:

Dim d_StartDate As DateTime = "1-10-2009"
Dim i_NumberOfDays As Integer = 12
Dim i_CalculateNumberOfDays As Integer 

If i_NumberOfDays > (5 - d_StartDate.DayOfWeek) Then
    i_CalculateNumberOfDays = i_NumberOfDays
Else
    i_CalculateNumberOfDays = i_NumberOfDays + (Int(((i_NumberOfDays + (7 - d_StartDate.DayOfWeek)) / 5)) * 2)
End If

MsgBox(DateAdd(DateInterval.Day, i_CalculateNumberOfDays, d_StartDate))

我尝试使用以下代码解释:

''' create variables to begin with
Dim d_StartDate as Date = "1-10-2009"
Dim i_NumberOfDays as Integer = 5

''' create var to store number of days to calculate with
Dim i_AddNumberOfDays as Integer 


''' check if amount of businessdays to add exceeds the 
''' amount of businessdays left in the week of the startdate
If i_NumberOfDays > (5 - d_StartDate.DayOfWeek) Then


    ''' start by substracting days in week with the current day,
    ''' to calculate the remainder of days left in the current week
    i_AddNumberOfDays = 7 - d_StartDate.DayOfWeek

    ''' add the remainder of days in this week to the total
    ''' number of days we have to add to the date
    i_AddNumberOfDays += i_NumberOfDays

    ''' divide by 5, because we need to know how many 
    ''' business weeks we are dealing with
    i_AddNumberOfDays = i_AddNumberOfDays / 5

    ''' multiply the integer of current business weeks by 2
    ''' those are the amount of days in the weekends we have 
    ''' to add to the total
    i_AddNumberOfDays = Int(i_AddNumberOfDays) * 2

    ''' add the number of days to the weekend days
    i_AddNumberOfDays += i_NumberOfDays

Else

    ''' there are enough businessdays left in this week
    ''' to add the given amount of days
    i_AddNumberOfDays = i_NumberOfDays

End If

''' this is the numberof dates to calculate with in DateAdd
dim d_CalculatedDate as Date
d_CalculatedDate = DateAdd(DateInterval.Day, i_AddNumberOfDays, d_StartDate)

提前感谢您的意见和建议。

10 个答案:

答案 0 :(得分:1)

Public Shared Function AddBusinessDays(ByVal startDate As DateTime, _
                                       ByVal businessDays As Integer) As DateTime
    Dim di As Integer
    Dim calendarDays As Integer

    '''di: shift to Friday. If it's Sat or Sun don't shift'
    di = (businessDays - Math.Max(0, (5 - startDate.DayOfWeek)))

    ''' Start = Friday -> add di/5 weeks -> end = Friday'
    ''' -> if the the remaining (<5 days) is > 0: add it + 2 days (Sat+Sun)'
    ''' -> shift back to initial day'
    calendarDays = ((((di / 5) * 7) _
                   + IIf(((di Mod 5) <> 0), (2 + (di Mod 5)), 0)) _
                   + (5 - startDate.DayOfWeek))

    Return startDate.AddDays(CDbl(calendarDays))

End Function

答案 1 :(得分:0)

您的计划似乎应该有效。确保将它包装在一个函数中,而不是在每个使用它的地方进行计算,这样如果/当你发现需要考虑假期时,你就不必在很多地方进行更改。

我能想到实现假期支持的最佳方式是在循环中一次添加一天。每次迭代,检查它是周末还是假日,以及是否添加另一天并继续(跳过它)。下面是伪代码的一个例子(我不知道VB);不保证其正确。当然,您需要为isWeekend()和isHoliday()提供自己的实现。

function addBusinessDays(startDate, numDays)
{
    Date newDate = startDate;
    while (numDays > 0)
    {
         newDate.addDays(1);
         if (newDate.isWeekend() || newDate.isHoliday())
             continue;

         numDays -= 1;
    }
    return newDate;
}

我对假期的第一个想法是简单地查看开始日期和结束日期之间的假期数量并将其添加到您的计算中,但当然这不起作用,因为结束日期取决于该间隔内的假期数。我认为迭代解决方案是您度假的最佳选择。

答案 2 :(得分:0)

我正在使用此代码计算日期:

    dayOfWeek = startDate.DayOfWeek
    weekendDays = 2 * Math.Floor((dayOfWeek + businessDays - 0.1) / 5)
    newDate = startDate.AddDays(businessDays + weekendDays)

第二行计算我们必须添加的完整周末数,然后将它们乘以2以获得天数。

如果(dayOfWeek + businessDays)是5的倍数,并且最终日期是星期五,则使用额外的-0.1常量来避免添加天数。

答案 3 :(得分:0)

我使用.DayOfWeek函数来检查它是否是一个周末。这不包括假期实施。它已经过测试。我意识到这个问题已经过时但是接受的答案没有用。但是,我确实感觉它有多干净,所以我想我会更新它并发布。我确实改变了while循环中的逻辑。

Function AddBusinessDays(startDate As Date, numberOfDays As Integer) As Date
    Dim newDate As Date = startDate
    While numberOfDays > 0
        newDate = newDate.AddDays(1)

        If newDate.DayOfWeek() > 0 AndAlso newDate.DayOfWeek() < 6 Then '1-5 is Mon-Fri
            numberOfDays -= 1
        End If

    End While
    Return newDate
End Function

答案 4 :(得分:0)

Private Function AddBusinessDays(ByVal dtStartDate As DateTime, ByVal intVal As Integer) As DateTime

    Dim dtTemp As DateTime = dtStartDate

    dtTemp = dtStartDate.AddDays(intVal)

    Select Case dtTemp.DayOfWeek
        Case 0, 6
            dtTemp = dtTemp.AddDays(2)
    End Select

    AddBusinessDays = dtTemp

End Function

答案 5 :(得分:0)

请检查此代码以添加工作日

Dim strDate As Date = DateTime.Now.Date
Dim afterAddDays As Date
Dim strResultDate As String
Dim n As Integer = 0

For i = 1 To 15
    afterAddDays = strDate.AddDays(i)
    If afterAddDays.DayOfWeek = DayOfWeek.Saturday Or afterAddDays.DayOfWeek = DayOfWeek.Sunday Then
        n = n + 1
    End If
Next

strResultDate = afterAddDays.AddDays(n).ToShortDateString()

答案 6 :(得分:0)

Private Function AddXWorkingDays(noOfWorkingDaysToAdd As Integer) As Date

    AddXWorkingDays = DateAdd(DateInterval.Weekday, noOfWorkingDaysToAdd + 2, Date.Today)
    If Weekday(Today) + noOfWorkingDaysToAdd < 6 Then AddXWorkingDays = DateAdd(DateInterval.Weekday, 2, Date.Today)

End Function

答案 7 :(得分:0)

一种方法是从开始日期开始迭代,如果日期不是星期六或星期日,则每次迭代加一次或减去一天。如果作为iAddDays传递零,则该函数将返回dDate,即使该日期是星期六或星期日。如果可能出现这种情况,你可以使用逻辑来获得你正在寻找的结果。

 Public Function DateAddWeekDaysOnly(ByVal dDate As DateTime, ByVal iAddDays As Int32) As DateTime
    If iAddDays <> 0 Then
        Dim iIncrement As Int32 = If(iAddDays > 0, 1, -1)
        Dim iCounter As Int32

        Do
            dDate = dDate.AddDays(iIncrement)
            If dDate.DayOfWeek <> DayOfWeek.Saturday AndAlso dDate.DayOfWeek <> DayOfWeek.Sunday Then iCounter += iIncrement
        Loop Until iCounter = iAddDays
    End If

    Return dDate
End Function

答案 8 :(得分:0)

Easy way

function addWerktage($date,$tage){
    for($t=0;$t<$tage;$t++){
        $date   = $date + (60*60*24);
        if(date("w",$date) == 0 || date("w",$date) == 6){ $t--; }
    }
    return $date;
}

答案 9 :(得分:-2)

Dim result As Date
    result = DateAdd("d", 2, Today)
    If result.DayOfWeek = DayOfWeek.Saturday Then
        result = DateAdd("d", 2, result)
        MsgBox(result)
    ElseIf result.DayOfWeek = DayOfWeek.Sunday Then
        result = DateAdd("d", 1, result)
        MsgBox(result)
    ElseIf result.DayOfWeek = DayOfWeek.Monday Then
        MsgBox(result)
    ElseIf result.DayOfWeek = DayOfWeek.Tuesday Then
        MsgBox(result)
    ElseIf result.DayOfWeek = DayOfWeek.Wednesday Then
        MsgBox(result)
    ElseIf result.DayOfWeek = DayOfWeek.Thursday Then
        MsgBox(result)
    ElseIf result.DayOfWeek = DayOfWeek.Friday Then
        MsgBox(result)
    End If