2014-08-27 2 views
-3

Я получаю время как 23300000 i.e. hhMMssmm формат как строка , и я хочу рассчитать разницу таких двух значений.Расчет времени в Excel VBA

Здесь hh - часы, MM - минуты, ss - секунды, а mm - 60 секунд. Использование VBA для Excel 2003

+0

как вы планируете рассчитать разницу между датой, которая проходит на следующий день? То есть. 23:30 и 1:30 на следующий день? – 2014-08-27 11:19:44

+0

Нет значений в тот же день. поэтому 1:30 никогда не будет там. Он всегда будет максимальным, как '24000000' –

+0

ну, вам нужна некоторая логика if-else для этого, особенно часть' mm'. почему бы вам не показать нам, что вы пробовали, и рассказать, что не работает, и тогда мы сможем помочь вам: – 2014-08-27 11:36:19

ответ

1

Этот UDF возвращает абсолютное значение разности в секунд

Public Function tDiff(s1 As String, s2 As String) As Double 
' 
' calculates the absolute value of the differences 
' returns the answer in seconds 
' 
    Dim hrs As Double, mins As Double, secs As Double, sixt As Double 
    Dim tVal1 As Double, tVal2 As Double 

    hrs = CDbl(Mid(s1, 1, 2)) * 60 * 60 
    mins = CDbl(Mid(s1, 3, 2)) * 60 
    secs = CDbl(Mid(s1, 5, 2)) 
    sixt = CDbl(Mid(s1, 7, 2))/60 
    tVal1 = hrs + mins + secs + sixt 

    hrs = CDbl(Mid(s2, 1, 2)) * 60 * 60 
    mins = CDbl(Mid(s2, 3, 2)) * 60 
    secs = CDbl(Mid(s2, 5, 2)) 
    sixt = CDbl(Mid(s2, 7, 2))/60 
    tVal2 = hrs + mins + secs + sixt 

    If tVal1 > tVal2 Then 
     tDiff = tVal1 - tVal2 
    Else 
     tDiff = tVal2 - tVal1 
    End If 
End Function 
+0

Я подозреваю, что OP хотел бы, чтобы возвращаемое значение также было строкой в ​​том же формате, что и входной;) – 2014-08-27 12:18:14

+1

@mehow Я был не уверен в форме или формате результата. Я опубликовал один вариант. Если * Rohit * хотел бы получить другой формат, я буду обновлять свой ответ. –

1

Как о чем-то вроде этого:

Public Sub test() 
    Dim ms1 As Double 
    Dim ms2 As Double 

    ms1 = ToSeconds(23142700) 
    ms2 = ToSeconds(23311500) 

    Debug.Print "Difference between dates in seconds: " & ms2 - ms1 
End Sub 


Public Function ToSeconds(number As Long) As Double 
    Dim hh As Long 
    Dim mm As Long 
    Dim ss As Long 
    Dim ms As Long 

    ms = (number Mod (100^1))/(100^0) 
    ss = (number Mod (100^2) - ms)/(100^1) 
    mm = (number Mod (100^3) - ss * (100^1) - ms)/(100^2) 
    hh = (number Mod (100^4) - mm * (100^2) - ss * (100^1) - ms)/(100^3) 

    ToSeconds = ms * 1/60 + ss + mm * 60 + hh * 60 * 60 
End Function 

The ToSeconds() функция преобразует ваш номер в секундах, и вы можете делать свои расчеты на основе этого.

+0

Достаточно честно - отредактировал функцию, чтобы вернуть количество секунд, прошедших с полуночи. – Bogey

+0

хорошо сделано ++ для обновления – 2014-08-27 12:28:06

0

Хотя это решение может быть не таким коротким, как другие, я считаю, что это очень легко понять. Не все здесь может быть необходимо, но вы можете найти некоторые из них полезными в будущем.

Подпрограмма run позволяет запускать функцию test с указанными вами значениями.
Функциональные тесты testtimeDiff & timeSum логика.
Функция timeDiff находит временную разницу между t1 и t0.
Функция timeSum находит временную сумму t1 и t0.
Функция asDuration удаляет суффикс AM/PM из значения времени.
Функция asMilitary преобразует 12-часовой формат в 24-часовой формат.
Функция concat, которую я создал для более легкой конкатенации строк.

Sub Main() 'Run Test 
    MsgBox Test("0:29:0", "23:30:0") 
End Sub 

Function Test(startT As Date, endT As Date) 'Test timeDiff & timeSum logic 
    Dim nextShift As Date, prevShift As Date, hours As Date 

    hours = timeDiff(endT, startT) 
    prevShift = timeDiff(startT, "0:30:0") 
    nextShift = timeSum("0:30:0", endT)   

    Test = concat("Start -", startT, "", "End - ", endT, "", "Duration -", asDuration(hours), "", "Next Shift: ", nextShift, "", "Prev Shift: ", prevShift) 
End Function 


Function timeDiff(t1 As Date, t0 As Date) As Date 'Return Time1 minus Time0 
    Dim units(0 To 2) As String 

    units(0) = Hour(t1) - Hour(t0) 
    units(1) = Minute(t1) - Minute(t0) 
    units(2) = Second(t1) - Second(t0) 

    If units(2) < 0 Then 
     units(2) = units(2) + 60 
     units(1) = units(1) - 1 
    End If 

    If units(1) < 0 Then 
     units(1) = units(1) + 60 
     units(0) = units(0) - 1 
    End If 

    units(0) = IIf(units(0) < 0, units(0) + 24, units(0)) 
    timeDiff = Join(units, ":") 
End Function 


Function timeSum(t1 As Date, t0 As Date) As Date 'Return Time1 plus Time0 
    Dim units(0 To 2) As String 

    units(0) = Hour(t1) + Hour(t0) 
    units(1) = Minute(t1) + Minute(t0) 
    units(2) = Second(t1) + Second(t0) 

    If units(2) >= 60 Then 
     units(2) = units(2) Mod 60 
     units(1) = units(1) + 1 
    End If 

    If units(1) >= 60 Then 
     units(1) = units(1) Mod 60 
     units(0) = units(0) + 1 
    End If 

    units(0) = IIf(units(0) >= 24, units(0) Mod 24, units(0)) 
    timeSum = Join(units, ":") 
End Function 


Function asDuration(time As Date) As String 'Display as duration; Remove AM/PM suffix from time 
    time = asMilitary(time) 
    asDuration = Left(time, Len(time)) 
End Function 


Function asMilitary(time As Date) As String 'Convert 12-hour format to 24-hour-format 
    asMilitary = Hour(time) & ":" & Minute(time) & ":" & Second(time) 
End Function 


Function concat(ParamArray var() As Variant) As String 'Return arguments of function call concatenated as a single string 
    For Each elem In var() 
     concat = IIf(elem <> "", concat & elem & " ", concat & vbNewLine) 
    Next 
End Function 
Смежные вопросы