0

在 VBScript 中是否可以将这种 20:72:84(hh:mm:ss) 持续时间转换为 21:13:24 (hh:mm:ss) 格式?

是的,显然我们可以循环通过它,但我想避免这种Loopy技术。

代码

根据Siddharth解决方案 - 我只是修改了代码以适应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我收到Type mismatch关于该行的错误timeArray = Split(strTime, ":")

谢谢,

4

5 回答 5

2

这是你正在尝试的吗?

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

快照

在此处输入图像描述

编辑(跟进)

我上面给出的代码是用于VBA-Excel因为它是你的标签之一

对于VB-Script,使用此代码

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

高温高压

于 2012-12-27T11:49:09.217 回答
2
  1. 拆分数组
  2. 使用将每个部分添加到空白时间dateadd()
  3. 使用 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()
    

输出21:13:24

编辑:应 TS 要求的额外评论

于 2012-12-28T11:04:05.557 回答
1

这似乎很明显是一个“ XY问题”:OP正在寻找一种解决方法来处理格式错误的数据,而不是首先弄清楚数据是如何变得格式错误的(并防止它发生)。

20:72:84不是任何标准的持续时间的逻辑表示,并且创建该字符串的任何内容都是错误的。

从技术上讲,根据ISO-8601(被认为是“涵盖日期和时间相关数据交换的国际标准”),持续时间应表示为PnYnMnDTnHnMnS

也就是说,我也会选择HH:MM:SS......但它应该 [显然?] 永远不会显示超过 59 秒或 59 分钟,任何超过我们的十进制(又名Base 10)数字系统应该计算在内...0.8, 0.9, 0.10, 0.11...。(大声笑,“零点十一”


固定持续时间

无论如何,这是一个老问题,我们不知道你是如何得到这个奇怪的数字的,但正如其他人所建议的,我会用Split它来修复它,尽管我更喜欢压缩形式:

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

上面的函数将通过将每个部分转换为秒、求和,然后Date在使用之前临时转换为 aFormat以按预期显示它来修复“不稳定”的持续时间。

需要注意的是,输入输出都不是有效的 Excel DateTime ( Date),因此两者都声明为Strings。

示例用法:

MsgBox fixWonkyDuration("20:72:84")  'returns "21:13:24"

转换为秒(用于比较、计算等)

顺便说一句,当您在格式上有一个有效的持续时间HH:MM:SS,但想用它进行计算或比较时,最简单的方法是首先在 和 的帮助下将其转换为TimeValueCDbl

最快的方法:

Function DurationToSeconds(d As String) As Long
    DurationToSeconds = CDbl(TimeValue(d)) * 86400#
End Function

示例用法:

MsgBox DurationToSeconds("21:13:24")  'returns 76404
于 2018-10-18T21:49:17.673 回答
0

好吧,您可以拆分为 3 个变量:h、m 和 s。然后检查是否 s>60。如果是,m=m+s/60 和 s=s%60。对于 m 变量也是如此:

if(m>60) then
    h=h+m/60
    m=m%60

然后,连接 h、m 和 s。

于 2012-12-27T09:59:36.803 回答
0

这是太多的文字,无法发表评论。

当您输入20:72:33任何General格式的单元格时,它会显示一个序列号。例如0.883715278

然后将单元格格式更改为Time. 它为您提供了您想要查看的格式和数据。

然而

上述语句仅在您的秒数为below 60. 如果输入60, 61, 84, '100' 等。它不起作用。

所以也许你可以像你现在正在使用的所有干扰代码一样干扰它;)

它尽可能丑陋。mod 60继续,seconds然后将单元格格式更改为时间。或者就像使用亚历克斯在他的回答中出现的内容一样。 它很干净,并在数学上保证了您所需的输出。

于 2012-12-27T10:46:16.803 回答