Добавление дней без выходных

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

Нет простого способа добавить количество дней недели в Date. Я бы предложил петлю Do. Начните с количества дней, которое нужно добавить, и в цикле добавьте 1 день. Если результат - будний день, вычтите из числа 1. Продолжайте, пока число не достигнет нуля.

jmcilhinney 19.03.2018 02:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
432
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вот метод расширения, который вы можете вызывать так же, как и 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

Я добавил новую реализацию расширения, представленного ранее, которое улучшает исходное.

jmcilhinney 20.04.2018 13:19

Вот еще один способ сделать это. Я думаю, что это довольно просто - особенно если вы делаете расчет всего несколько раз.

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 для удаления государственных праздников.

Простой.

Другие вопросы по теме