Is it Possible in VBScript to convert such 20:72:84(hh:mm:ss) duration to 21:13:24 (hh:mm:ss) format?
Yes obviously we can Loop through it but I want to avoid such Loopy
technique.
CODE
As per the Siddharth
solution - I just modified the code as it to fit with VBScript platform
Option Explicit
Dim S
S=Convert("23:61:61")
MsgBox(s)
Function Convert(strTime) 'As String
Dim timeArray()
Dim h , m , s
MsgBox("Hi")
'On Error Resume Next
timeArray = Split(strTime, ":")
h = timeArray(0): m = timeArray(1): s = timeArray(2)
REM If err then
REM MsgBox(err)
REM err.clear
REM Exit Function
REM End if
Do Until s < 60
s = s - 60
m = m + 1
Loop
Do Until m < 60
m = m - 60
h = h + 1
Loop
Do Until h < 24
h = h - 24
Loop
Convert = Format(h, "00") & ":" & Format(m, "00") & ":" & Format(s, "00")
'on Error Goto 0
'Exit Function
'Whoa:
'Convert = "Error! CYDD!" '<~~ CYDD : Check Your Data Dude :)
End Function
EDIT1 I am getting an error as Type mismatch
to the line timeArray = Split(strTime, ":")
Thanks,
Is this what you are trying?
Option Explicit
Sub Sample()
Debug.Print Convert("23:61:61")
Debug.Print Convert("24:61:61")
Debug.Print Convert("20:72:84")
Debug.Print Convert("Hello World")
End Sub
Function Convert(strTime As String) As String
Dim timeArray() As String
Dim h As Long, m As Long, s As Long
On Error GoTo Whoa
timeArray = Split(strTime, ":")
h = timeArray(0): m = timeArray(1): s = timeArray(2)
Do Until s < 60
s = s - 60
m = m + 1
Loop
Do Until m < 60
m = m - 60
h = h + 1
Loop
Do Until h < 24
h = h - 24
Loop
Convert = Format(h, "00") & ":" & Format(m, "00") & ":" & Format(s, "00")
Exit Function
Whoa:
Convert = "Error! CYDD!" '<~~ CYDD : Check Your Data Dude :)
End Function
SNAPSHOT
EDIT (FOLLOWUP)
The code that I gave above is for VBA-Excel
( as it is one of your tags )
For VB-Script
, use this code
MsgBox Convert("23:61:61")
MsgBox Convert("24:61:61")
MsgBox Convert("20:72:84")
MsgBox Convert("Hello World")
Function Convert(strTime)
Dim timeArray
Dim h, m, s, hh, mm, ss
On Error Resume Next
timeArray = Split(strTime, ":", -1, 1)
h = timeArray(0): m = timeArray(1): s = timeArray(2)
If Err Then
Err.Clear
Exit Function
End If
Do Until s < 60
s = s - 60
m = m + 1
Loop
Do Until m < 60
m = m - 60
h = h + 1
Loop
' As per latest request
'Do Until h < 24
'h = h - 24
'Loop
If Len(Trim(h)) = 1 Then hh = "0" & h Else hh = h
If Len(Trim(m)) = 1 Then mm = "0" & m Else mm = m
If Len(Trim(s)) = 1 Then ss = "0" & s Else ss = s
Convert = hh & ":" & mm & ":" & ss
On Error GoTo 0
End Function
HTH
dateadd()
rebuild the time to a well formatted string using a stringbuilder
' This splits the string in an hours, minutes and seconds part. ' the hours will be in dArr(0), minutes in dArr(1) and seconds in dArr(2) dArr = split("20:72:84", ":") ' Add the hours to an empty date and return it to dt1 dt1 = dateadd("h", dArr(0), empty) ' Add the minutes to dt1. Note: Minutes are noted as "n" and not "m" because the ' "m" is reserved for months. To find out more about the dateadd() please look here: ' http://www.w3schools.com/vbscript/func_dateadd.asp ' When the minutes are bigger than they fit in the date, it automatically falls over to ' next hour. dt1 = dateadd("n", dArr(1), dt1) ' Also add the seconds (the third part of the array) to dt1, also the seconds ' automatically fall over when too large. dt1 = dateadd("s", dArr(2), dt1) ' Now that we created a date, we only have to format it properly. I find it the most easy ' way to do this is with a dotnet stringbuilder, because we can separate code and ' format. The CreateObject creates the stringbuilder. We chain the AppendFormat ' and the ToString methods to it, so actually these are three statements in one. ' Mind the HH in the HH:mm:ss format string, hh means 12 hour notation, HH means 24 ' hour notation. msgbox CreateObject("System.Text.StringBuilder").AppendFormat("{0:HH:mm:ss}", dt1).toString()
outputs 21:13:24
EDIT: Extra comments by request of TS
This seems to be quite obviously an " XY Problem ": the OP is seeking a workaround to deal with a malformed piece of data, instead of figuring how the data is becoming malformed in the first place (and preventing it from happening).
20:72:84
is not a logical representation of duration by any standard, and whatever created that string is erroneous.
Technically , according to ISO-8601 (considered the "international standard for covering exchange of date and time related data"), duration should be expressed as PnYnMnDTnHnMnS
.
That said, I would also opt for HH:MM:SS
... but it should [obviously?] never show more than 59 seconds or 59 minutes, any more than our decimal (aka, Base 10 ) number system should count ...0.8, 0.9, 0.10, 0.11...
. (lol, "zero point eleven" )
Regardless, it's an old question and we don't know how you got this strange number, but as others have suggested, I would use Split
to fix it, although my preference is a more compressed form:
Function fixWonkyDuration(t As String) As String
fixWonkyDuration = Format(((Split(t, ":")(0) * 60 + Split(t, ":")(1)) _
* 60 + Split(t, ":")(2)) / 86400, "HH:mm:ss")
End Function
The function above will fix a "wonky" duration by converting each section into seconds, summing, then converting temporarily to a Date
before using Format
to display it as intended.
It's important to note that neither the input nor output is a valid Excel DateTime ( Date
), so both are declared as String
s.
MsgBox fixWonkyDuration("20:72:84") 'returns "21:13:24"
Incidentally, when you have a valid duration in HH:MM:SS
format, but want to do calculations or comparisons with it, it's easiest to first convert it to seconds with the help of TimeValue
and CDbl
.
The quickest method:
Function DurationToSeconds(d As String) As Long
DurationToSeconds = CDbl(TimeValue(d)) * 86400#
End Function
MsgBox DurationToSeconds("21:13:24") 'returns 76404
Well, you can split into 3 variables: h,m and s. And then check if s>60. And if it is, m=m+s/60 and s=s%60. The same for the m variable:
if(m>60) then
h=h+m/60
m=m%60
Then, concate h, m and s.
This is too much text to put in a comment.
When you enter 20:72:33
into any cell that is on General
format it will show you a serial number. Eg 0.883715278
Then you change the cell format to Time
. And it gives you the format and data you want to see.
The above statement only works as long as your seconds are below 60
. If you enter 60, 61, 84
, '100', etc. It doesn't work.
So perhaps you can jam it like all the jamming codes perhaps you are using right now. ;)
It's as ugly as it could get. Do mod 60
on seconds
and then change cell format to Time. Or just as might as use what Alex shows up there in his answer. It's clean and gurantees your the desired output mathematically.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.