0

aspx Webページで使用するvb.netの2つの日付/時刻間の時間を計算しようとしています。ここや他の情報源で年齢を検索しましたが、あまり遠くには行きません. 私が見つけたすべての例は、PHP または SQL 関連のものです。

基本的に私は次のものを持っています....

Dim StartDateTime As DateTime = #5/27/2013 6:00:00 AM#

Dim FinishDateTime As DateTime = #5/28/2013 10:30:00 AM#

Dim Minutes As Long = DateDiff(DateInterval.Minute, StartDateTime, FinishDateTime, Microsoft.VisualBasic.FirstDayOfWeek.Monday)

開始と終了の間の分数を計算します。問題は、設定された営業時間 (9-5) の時間を計算したいだけなので、例では 9.5 時間または 570 分を返す必要があり、その期間が週末にかかる場合は最終的には計算されません。

開始時間はいつでも構いません (したがって、営業時間の前後になる可能性があります)。終了時間は通常、営業時間内ですが、それも任意であると想定する必要があります。

おそらく、膨大な量の IF ステートメントを使用してこれを達成できますが、これは非効率的なアプローチのように思えます。誰かが私を正しい方向に導くための指針があれば知りたいです。

どうもありがとう

4

3 に答える 3

1

次のように、2 つの日付 (両端を含む) から休日と週末を除いた営業日のリストを取得する関数を既に作成しています。

Function GetWorkingDates(startDate As Date, endDate As Date, holidayDates As Date()) As List(Of Date)
    If endDate < startDate Then
        Throw New ArgumentOutOfRangeException("endDate", "Value must be equal or larger than 'startDate' parameter.")
    End If

    Dim listDate As List(Of Date) = Enumerable.Range(0, 1 + CInt((endDate - startDate).TotalDays)).Select(Function(n) startDate.AddDays(n)).ToList

    ' if defined, remove holidays from listDate
    If holidayDates IsNot Nothing Then listDate.RemoveAll(Function(d) holidayDates.Contains(d))

    ' remove weekends as defined below
    Dim weekends As DayOfWeek() = {DayOfWeek.Saturday, DayOfWeek.Sunday}
    listDate.RemoveAll(Function(d) weekends.Contains(d.DayOfWeek))

    Return listDate
End Function

合計時間を取得するために、上記の既存の関数の結果から合計タイムスパンを取得する新しい関数を作成しました。

Function GetTotalWorkingTimeSpan(startDateTime As Date, endDateTime As Date, startWorkTime As TimeSpan, endWorkTime As TimeSpan, holidayDates As Date()) As TimeSpan
    If endDateTime < startDateTime Then
        Throw New ArgumentOutOfRangeException("endDate", "Value must be equal or larger than 'startDate' parameter.")
    End If

    If endWorkTime < startWorkTime Then
        Throw New ArgumentOutOfRangeException("endWorkTime", "Value must be equal or larger than 'startWorkTime' parameter.")
    End If

    ' get list of working days minus weekends and holidays
    Dim lstWorkDays As List(Of Date) = GetWorkingDates(startDateTime.Date, endDateTime.Date, holidayDates)

    ' get total minutes by bultiplying total working days and total minutes per day
    Dim totalMinutes As Double = lstWorkDays.Count * (endWorkTime - startWorkTime).TotalMinutes

    ' deduct the first day's hour if occured later than the startWorkTime, only if startDateTime is a working day
    If lstWorkDays.Contains(startDateTime.Date) Then
        Dim minutesOffset As Double = (startDateTime.TimeOfDay - startWorkTime).TotalMinutes
        If minutesOffset > 0 Then totalMinutes -= minutesOffset
    End If

    ' deduct the last day's hour if occured ealier than the endWorkTime, only if endDateTime is a working day
    If lstWorkDays.Contains(endDateTime.Date) Then
        Dim minutesOffset As Double = (endWorkTime - endDateTime.TimeOfDay).TotalMinutes
        If minutesOffset > 0 Then totalMinutes -= minutesOffset
    End If

    Return TimeSpan.FromMinutes(totalMinutes)
End Function

あなたのデータを使用して、テスト コンソールを作成しました。

Sub Main()
    Dim sdt As Date = #5/27/2013 6:00:00 AM#
    Dim edt As Date = #5/28/2013 10:30:00 AM#
    Dim hols() As Date = {} ' add holiday dates here

    Dim lst As List(Of Date) = GetWorkingDates(sdt, edt, Nothing) ' or simply Nothing to not check for holidays
    Console.WriteLine("Num of working days = " & lst.Count)
    Console.WriteLine()

    Console.WriteLine("List of working dates:")
    lst.ForEach(Sub(d) Console.WriteLine("* " & d.ToLongDateString))
    Console.WriteLine()

    Dim totalWorkingTimeSpan As TimeSpan = GetTotalWorkingTimeSpan(sdt, edt, New TimeSpan(9, 0, 0), New TimeSpan(17, 0, 0), hols)
    Console.WriteLine("Total working hours = " & totalWorkingTimeSpan.TotalMinutes & " minutes, or " & totalWorkingTimeSpan.TotalHours & " hours")

    PromptExit()
End Sub

コンソール アプリの出力:

于 2013-06-03T11:00:02.770 に答える
0

これは、コードを使用して実現できます。開始時刻と終了時刻を稼働時間に「正規化」するために必要な計算と、週末を決定するために必要な追加の計算がありますが、それは比較的単純な演習です。

    ' Define the start and end hour of the work day
    Const START_HOUR As Integer = 9
    Const FINISH_HOUR As Integer = 17

    Dim StartDateTime As DateTime = #5/27/2013 6:00:00 AM#

    Dim FinishDateTime As DateTime = #5/28/2013 10:30:00 AM#

    If StartDateTime.Hour < START_HOUR Then
        ' If the current hour is less than the start hour, go to the start of the current day
        StartDateTime = New DateTime(StartDateTime.Year, StartDateTime.Month, StartDateTime.Day, START_HOUR, 0, 0)

    ElseIf StartDateTime.Hour > FINISH_HOUR Then
        ' If the current hour is greater than the end hour, go to the start of the next day
        StartDateTime = New DateTime(StartDateTime.Year, StartDateTime.Month, StartDateTime.Day + 1, START_HOUR, 0, 0)

    End If

    If FinishDateTime.Hour < START_HOUR Then
        ' If the current hour is less than the start hour, go back to the end of the previous day
        FinishDateTime = New DateTime(FinishDateTime.Year, FinishDateTime.Month, FinishDateTime.Day - 1, FINISH_HOUR, 0, 0)

    ElseIf FinishDateTime.Hour > FINISH_HOUR Then
        ' If the current hour is greater than the end hour, go to the end hour of the current day
        FinishDateTime = New DateTime(FinishDateTime.Year, FinishDateTime.Month, FinishDateTime.Day, FINISH_HOUR, 0, 0)

    End If

    ' Determine the total number of actual days the date range crosses
    Dim Days = Math.Ceiling(FinishDateTime.Subtract(StartDateTime).TotalDays)

    Dim Weekends As Double

    ' Determine the number of weekends (might need work)
    If FinishDateTime.DayOfWeek > StartDateTime.DayOfWeek Then
        ' I'm sure this needs work
        Weekends = Math.Floor(Days / 7) + 1
    Else
        Weekends = Math.Floor(Days / 7)
    End If

    ' Determine the number of minutes between the start of the work day and the actual start time
    Dim StartMinutesOffset = ((StartDateTime.Hour * 60) + StartDateTime.Minute) - (START_HOUR * 60)
    ' Determine number of minutes between the finish time and the end of the work day
    Dim FinishMinutesOffset = (FINISH_HOUR * 60) - ((FinishDateTime.Hour * 60) + FinishDateTime.Minute)

    ' The number of minutes is the number of days less 2 * the number of weekends less the start time offset less the finish time offset
    Dim TotalMinutes = (Days - (Weekends * 2)) * ((FINISH_HOUR - START_HOUR) * 60) - StartMinutesOffset - FinishMinutesOffset

    Debug.WriteLine(TotalMinutes)
于 2013-06-02T20:19:06.657 に答える
0

基本的には、開始から終了までの営業時間外の時間を計算するだけです

したがって、日付範囲の営業時間外の「テーブル」を作成します

2013 年 1 月 1 日 08:20 から 2013 年 3 月 1 日 17:30 だったとします。

1/1/2013 00:00:00 to 1/1/2013 08:59:59
1/1/2013 17:00:00 to 1/1/2013 23:59:59
2/1/2013 00:00:00 to 1/2/2013 08:59:59
2/1/2013 17:00:00 to 1/2/2013 23:59:59
3/1/2013 00:00:00 to 3/1/2013 08:59:59
3/1/2013 17:00:00 to 3/1/2013 23:59:59

次に、最初の開始時刻と最後の終了時刻を置き換えて取得します

1/1/2013 08:20:00 to 1/1/2013 08:59:59
1/1/2013 17:00:00 to 1/1/2013 23:59:59
2/1/2013 00:00:00 to 1/2/2013 08:59:59
2/1/2013 17:00:00 to 1/2/2013 23:59:59
3/1/2013 00:00:00 to 3/1/2013 08:59:59
3/1/2013 17:00:00 to 3/1/2013 17:30:00

上記の期間の合計が非営業時間です。したがって、end - start から減算するだけです。

これを行うさまざまな方法がたくさんあります。ここで検索すると、CTEを使用してSQLでそれを行う方法が見つかります

于 2013-06-02T15:28:59.700 に答える