代码之家  ›  专栏  ›  技术社区  ›  arc95

添加避开周末的天数

  •  -1
  • arc95  · 技术社区  · 8 年前

    我有3个 DateTimePicker ,一个用于设置日期,第二个用于添加3天,第三个用于添加5个工作日。但我的代码计算不正确。 我“手动”计算未来天数,增加或减少当天的折旧天数。

      Private Sub Calculatedelivery()
        Dim normaldlvy As Integer
        Dim latedlvy As Integer
        If DateTimePicker1.Value.DayOfWeek = Day.Monday Then
            normaldlvy = 3
            latedlvy = 7
        End If
        If DateTimePicker1.Value.DayOfWeek = Day.Tuesday Then
            normaldlvy = 3
            latedlvy = 6
        End If
        If DateTimePicker1.Value.DayOfWeek = Day.Wednesday Then
            normaldlvy = 5
            latedlvy = 7
        End If
        If DateTimePicker1.Value.DayOfWeek = Day.Thursday Then
            normaldlvy = 5
            latedlvy = 7
        End If
        If DateTimePicker1.Value.DayOfWeek = Day.Friday Then
            normaldlvy = 5
            latedlvy  = 7
        End If
        If DateTimePicker1.Value.DayOfWeek = Day.Saturday Then
            normaldlvy = 4
            latedlvy = 6
        End If
        If DateTimePicker1.Value.DayOfWeek = Day.Sunday Then
            normaldlvy = 3
            latedlvy = 5
        End If
        DateTimePicker2.Value = DateTimePicker1.Value.AddDays(normaldlvy )
        DateTimePicker3.Value = DateTimePicker1.Value.AddDays(latedlvy)
    End Sub
    
    2 回复  |  直到 8 年前
        1
  •  3
  •   jmcilhinney    8 年前

    这里有一个扩展方法,您可以像调用之前一样调用它 AddDays :

    Imports System.Runtime.CompilerServices
    
    Public Module DateTimeExtensions
    
        <Extension>
        Public Function AddWeekDays(source As Date, value As Integer) As Date
            Dim result = source
    
            Do
                result = result.AddDays(1)
    
                If result.IsWeekDay() Then
                    value -= 1
                End If
            Loop Until value = 0
    
            Return result
        End Function
    
        <Extension>
        Public Function IsWeekDay(source As Date) As Boolean
            Return source.DayOfWeek <> DayOfWeek.Saturday AndAlso
                   source.DayOfWeek <> DayOfWeek.Sunday
        End Function
    
    End Module
    

    你可以这样称呼它:

    DateTimePicker3.Value = DateTimePicker1.Value.AddWeekDays(latedlvy)
    

    请注意,与 Date.AddDays ,该方法需要 Integer 而不是 Double 。而且,它只适用于正数。它可以改进,以几乎完全相同的方式工作 AddDays 但在这种情况下,您可能不需要这样做。

    如果你不确定扩展方法是如何工作的,我建议你阅读一下这个主题。

    编辑 :我对此方法做了一些工作,并对其进行了显著改进。它现在处理负值和分数值,就像 日期AddDays

    Imports System.Runtime.CompilerServices
    
    ''' <summary>
    ''' Contains methods that extend the <see cref="DateTime"/> structure.
    ''' </summary>
    Public Module DateTimeExtensions
    
        ''' <summary>
        ''' Gets a value indicating whether a <see cref="DateTime"/> value represents a week day.
        ''' </summary>
        ''' <param name="source">
        ''' The input <see cref="DateTime"/>, which acts as the <b>this</b> instance for the extension method.
        ''' </param>
        ''' <returns>
        ''' <b>true</b> if the represents a week day; otherwise <b>false</b>.
        ''' </returns>
        ''' <remarks>
        ''' All days other than Saturday and Sunday are considered week days.
        ''' </remarks>
        <Extension>
        Public Function IsWeekDay(source As Date) As Boolean
            Return source.DayOfWeek <> DayOfWeek.Saturday AndAlso
                   source.DayOfWeek <> DayOfWeek.Sunday
        End Function
    
        ''' <summary>
        ''' Returns a new <see cref="DateTime"/> that adds the specified number of week days to a specified value.
        ''' </summary>
        ''' <param name="source">
        ''' The input <see cref="DateTime"/>, which acts as the <b>this</b> instance for the extension method.
        ''' </param>
        ''' <param name="value">
        ''' A number of whole and fractional days. The <i>value</i> parameter can be negative or positive.
        ''' </param>
        ''' <returns>
        ''' An object whose value is the sum of the date and time represented by this instance and the number of week days represented by <i>value</i>.
        ''' </returns>
        ''' <remarks>
        ''' All days other than Saturday and Sunday are considered week days.
        ''' </remarks>
        <Extension>
        Public Function AddWeekDays(source As Date, value As Double) As Date
            'A unit will be +/- 1 day.
            Dim unit = Math.Sign(value) * 1.0
    
            'Start increasing the date by units from the initial date.
            Dim result = source
    
            'When testing for zero, allow a margin for precision error.
            Do Until Math.Abs(value) < 0.00001
                If Math.Abs(value) < 1.0 Then
                    'There is less than one full day to add so we need to see whether adding it will take us past midnight.
                    Dim temp = result.AddDays(value)
    
                    If temp.Date = result.Date OrElse temp.IsWeekDay() Then
                        'Adding the partial day did not take us into a weekend day so we're done.
                        result = temp
                        value = 0.0
                    Else
                        'Adding the partial day took us into a weekend day so we need to add another day.
                        result = result.AddDays(unit)
                    End If
                Else
                    'Add a single day.
                    result = result.AddDays(unit)
    
                    If result.IsWeekDay() Then
                        'Adding a day did not take us into a weekend day so we can reduce the remaining value to add.
                        value -= unit
                    End If
                End If
            Loop
    
            Return result
        End Function
    
    End Module
    
        2
  •  0
  •   Enigmativity    8 年前

    这是另一种方法。我认为这是一个相当直接的问题,尤其是如果你只做了几次计算的话。

    Dim someDate As DateTime = DateTime.Now.Date
    
    Dim dates = _
            Enumerable _
                .Range(1, 100000) _
                .Select(Function (x) someDate.AddDays(x)) _
                .Where(Function (x) x.DayOfWeek <> DayOfWeek.Saturday) _
                .Where(Function (x) x.DayOfWeek <> DayOfWeek.Sunday)
    
    Dim nextDate = dates.Take(5).First()
    

    这种方法的最大优点是,您还可以进一步添加 .Where 取消公共假日的呼吁。

    易于理解的