У меня есть 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





Вот метод расширения, который вы можете вызывать так же, как и 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, но в данном случае вам это, вероятно, не понадобится.
Если вы не знаете, как работают методы расширения, я предлагаю вам почитать по этой теме.
РЕДАКТИРОВАТЬ: Я поработал над этим методом и значительно улучшил его. Теперь он обрабатывает отрицательные и дробные значения, как и Date.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
Я добавил новую реализацию расширения, представленного ранее, которое улучшает исходное.
Вот еще один способ сделать это. Я думаю, что это довольно просто - особенно если вы делаете расчет всего несколько раз.
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 для удаления государственных праздников.
Простой.
Нет простого способа добавить количество дней недели в
Date. Я бы предложил петлюDo. Начните с количества дней, которое нужно добавить, и в цикле добавьте 1 день. Если результат - будний день, вычтите из числа 1. Продолжайте, пока число не достигнет нуля.