Sign in to follow this  
Followers 0
zbatev

Convert Time in String to Time Value

18 posts in this topic

Hi All,

This is very silly but I couldn't find a function that can convert this "09:00" to it's time value equivalent 09:00:00 AM.

I'm talking about the equivalent of VBScript's Timevalue function.

Share this post


Link to post
Share on other sites



I had to look up vbscript's TimeValue function. I don't quite understand what it is used for.

Is this similar to what you want:

http://www.autoitscript.com/autoit3/docs/libfunctions/_Date_Time_FileTimeToStr.htm


#include <ByteMe.au3>

Share this post


Link to post
Share on other sites

I had to look up vbscript's TimeValue function. I don't quite understand what it is used for.

Is this similar to what you want:

http://www.autoitscript.com/autoit3/docs/libfunctions/_Date_Time_FileTimeToStr.htm

Sorry about the assumption, for those who will be reading this thread and doesn't know about vbscript's functions

'save this as    filename.vbs

'use 1
varnow = now() 'mm/dd/yy hh:mm:ss AM/PM
msgbox "varnow = now()" & vblf & "timevalue(varnow)" & vblf & "Result>   " & timevalue(varnow),vbokonly,"USE 1: "

'use 2
msgbox "timevalue(" & chr(34) & "7:35 PM " & chr(34) & ")" & vblf & "Result>   " & timevalue("7:35 PM"),vbokonly,"USE 2: "

'use 3
msgbox "timevalue(" & chr(34) & "19:35" & chr(34) & ")" & vblf & "Result>   " & timevalue("19:35"),vbokonly,"USE 3: "

Thanks for that function (_Date_Time_FileTimeToStr) that is close to what I need but with this one I will also need to deal with the date since it's a required parameter. If only there is something else that handles time alone.

Share this post


Link to post
Share on other sites

I think I get it now. I wrote a little function that does what I think you want. It doesn't have safeguards to prevent mistakes, though.

#include <array.au3>
$value = InputBox("TimeFormat", "Enter a time to format: ")

$output = _ConvertTime($value)
MsgBox(0, "", $output)

Func _ConvertTime($timeToFormat)    
    $timeSplit = StringSplit($timeToFormat, ":")
    
    $hour = StringFormat("%02i", $timeSplit[1])
    
    If $timeSplit[0] > 1 Then
        $minute = StringFormat("%02i", $timeSplit[2])
    Else
        $minute = "00"
    EndIf
    
    If $timeSplit[0] > 2 Then
        $second = StringFormat("%02i", $timeSplit[3])
    Else
        $second = "00"
    EndIf   
    
    $formattedValue = $hour & ":" & $minute & ":" & $second
    
    Return($formattedValue)
EndFunc

#include <ByteMe.au3>

Share this post


Link to post
Share on other sites

@sleepydvdr: What about AM/PM handling? :)

@zbatev: Try this, tell me if it to your liking ;)

#include <Date.au3> ;only needed for the last couple examples, function works fine without it

;Author:smartee
Func _TimeValue($sTime)
    Local $avDate = StringRegExp($sTime, "(?i)^#?(\d+):(\d+)(?::(\d+))?(?:\s?(AM|PM))?#?$", 1)
    If @error Then Return SetError(1, 0, "")
    If UBound($avDate) <> 4 Then ReDim $avDate[4]
    If StringRegExp($avDate[2] & $avDate[3], "(?i)^\d*PM$") Then
        If $avDate[0] <= 12 Then $avDate[0] = Mod($avDate[0] + 12, 24)
    EndIf
    $avDate[3] = "AM"
    If $avDate[0] >= 12 Then
        $avDate[0] = Mod($avDate[0], 12)
        $avDate[3] = "PM"
    EndIf
    If $avDate[0] = 0 Then $avDate[0] = 12
    Return StringFormat("%02s:%02s:%02s %s", $avDate[0], $avDate[1], $avDate[2], $avDate[3])
EndFunc   ;==>_TimeValue

;Some examples
ConsoleWrite("5:59:43 PM = " & _TimeValue("5:59:43 PM") & @CRLF)
ConsoleWrite("4:00 = " & _TimeValue("4:00") & @CRLF)
ConsoleWrite("5:30pm = " & _TimeValue("5:30pm") & @CRLF)
ConsoleWrite("0:00 = " & _TimeValue("0:00") & @CRLF)
ConsoleWrite("15:16:17 = " & _TimeValue("15:16:17") & @CRLF)
ConsoleWrite("19:35 = " & _TimeValue("19:35") & @CRLF)
ConsoleWrite(_NowTime(4) & " = " & _TimeValue(_NowTime(4)) & @CRLF)
ConsoleWrite(_NowTime(5) & " = " & _TimeValue(_NowTime(5)) & @CRLF)

Hope this helps ;)

-smartee

Share this post


Link to post
Share on other sites

Also to note, if you want to use something like this as a regular part of AutoIt, create a file in AutoIt's Includes folder and name it something like Timevalue.au3. In that file, just put the function part of the above script. Then when you are writing a script, just add a #include and call the function by name. Like this:

#include <Timevalue.au3>

$output = _ConvertTime($value)

#include <ByteMe.au3>

Share this post


Link to post
Share on other sites

@sleepydvdr: What about AM/PM handling? ;)

@zbatev: Try this, tell me if it to your liking :D

#include <Date.au3> ;only needed for the last couple examples, function works fine without it

;Author:smartee
Func _TimeValue($sTime)
    Local $avDate = StringRegExp($sTime, "(?i)^#?(\d+):(\d+)(?::(\d+))?(?:\s?(AM|PM))?#?$", 1)
    If @error Then Return SetError(1, 0, "")
    If UBound($avDate) <> 4 Then ReDim $avDate[4]
    If StringRegExp($avDate[2] & $avDate[3], "(?i)^\d*PM$") Then
        If $avDate[0] <= 12 Then $avDate[0] = Mod($avDate[0] + 12, 24)
    EndIf
    $avDate[3] = "AM"
    If $avDate[0] >= 12 Then
        $avDate[0] = Mod($avDate[0], 12)
        $avDate[3] = "PM"
    EndIf
    If $avDate[0] = 0 Then $avDate[0] = 12
    Return StringFormat("%02s:%02s:%02s %s", $avDate[0], $avDate[1], $avDate[2], $avDate[3])
EndFunc   ;==>_TimeValue

;Some examples
ConsoleWrite("5:59:43 PM = " & _TimeValue("5:59:43 PM") & @CRLF)
ConsoleWrite("4:00 = " & _TimeValue("4:00") & @CRLF)
ConsoleWrite("5:30pm = " & _TimeValue("5:30pm") & @CRLF)
ConsoleWrite("0:00 = " & _TimeValue("0:00") & @CRLF)
ConsoleWrite("15:16:17 = " & _TimeValue("15:16:17") & @CRLF)
ConsoleWrite("19:35 = " & _TimeValue("19:35") & @CRLF)
ConsoleWrite(_NowTime(4) & " = " & _TimeValue(_NowTime(4)) & @CRLF)
ConsoleWrite(_NowTime(5) & " = " & _TimeValue(_NowTime(5)) & @CRLF)

Hope this helps :D

-smartee

Thanks @sleepydvdr ;) that's nice but I think I'll take @smartee's version, I think it's most complete.

Brilliant @smartee :) , thanks a lot I like this one! it's a keeper!

But I guess it's safe to say that there is no built in function for that thus the trouble! :D

Share this post


Link to post
Share on other sites

Oops I found me a mistake :)

If $avDate[0] <= 12 Then $avDate[0] = Mod($avDate[0] + 12, 24)
Should be
If $avDate[0] < 12 Then $avDate[0] = Mod($avDate[0] + 12, 24)

Now its a keeper ;)

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Also to note, if you want to use something like this as a regular part of AutoIt, create a file in AutoIt's Includes folder and name it something like Timevalue.au3. In that file, just put the function part of the above script. Then when you are writing a script, just add a #include and call the function by name. Like this:

#include <Timevalue.au3>

$output = _ConvertTime($value)

I know @smartee's code doesn't really need the <Date.au3> include but for say...

Does AutoIT handle double declaration of #include?

I mean for example if I do your suggestion and mistakenly added #include <Date.au3> again like this:

#include <Timevalue.au3>
#include <Date.au3> ;this one was already added in  <Timevalue.au3>

$output = _ConvertTime($value)
Edited by zbatev

Share this post


Link to post
Share on other sites

If you include the same file containing a user-function more than once, you will get a "Duplicate function" error. When writing an include file that may be used in this way, make sure that the top line contains #include-once to prevent that file from being included more than once.

Date.au3 has #include-once at the top so yes AutoIt will handle this possibility gracefully.

Share this post


Link to post
Share on other sites

Date.au3 has #include-once at the top so yes AutoIt will handle this possibility gracefully.

Nice tip! I'm full in throttle now! :) Thanks again, appreciate it!

Share this post


Link to post
Share on other sites

Here my version:

$time = "21:22:33"
MsgBox(0, "test", Convert2AMPM($time))

$time = "3:05:01"
MsgBox(0, "test", Convert2AMPM($time))

Func Convert2AMPM($time)
    Local $aToken = StringSplit($time, ":", 2)
    If Not IsArray($aToken) Then Return SetError(1, 0, "Error!")
    $time = $aToken[0]
    If $time < 0  Or $time > 23 Then Return SetError(2, 0, "Error!")
    Local $format = " pm", $t
    If $time < 12 Then $format = " am"
    $t = Mod($time, 12)
    If Not $t Then Return StringFormat("%02s:%02s:%02s %s", 12, $aToken[1], $aToken[2], $format)
    Return StringFormat("%02s:%02s:%02s %s", $t, $aToken[1], $aToken[2], $format)
EndFunc

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

@UEZ:

Nice :) but TimeValue in VBScript does more than convert 24h->12h format, it allows you to specify no seconds part if you wanted and AM/PM if you so prefer.

@all:

Found me another bug with the specifying AM thingy, now fixed, and packed into standard format with documentation for your convenience.

Download it here: TimeValueUDFv1.1.zip

If this link is broken, PM me I will re-upload a copy. ;)

See updated download below.

Regards,

-smartee

Edited by smartee

Share this post


Link to post
Share on other sites

I'm bored!

I did a less functional, but similar, routine a while back and found this line useful:

If Not Mod($hours, 12) Then $hours += 12 ; If 0 or 12 then add 12

You might work it in and get rid of one "If" comparison and one Mod() statement (the number of assign statements stays the same: 5), something like:

If UBound($avDate) <> 4 Then ReDim $avDate[4]
    If Not Mod($avDate[0], 12) Then $avDate[0] += 12 ; If 0 or 12 then add 12
    If $avDate[0] > 12 Then
        $avDate[0] -= 12
        $avDate[3] = "PM"
    Else
        If StringRegExp($avDate[2] & $avDate[3], "(?i)PM") Then
            $avDate[3] = "PM"
        Else
            $avDate[3] = "AM"
        Endif
    EndIf
    Return StringFormat("%02s:%02s:%02s %s", $avDate[0], $avDate[1], $avDate[2], $avDate[3])

It would be cool if the routine could handle a string like "2 PM" as well, but I'm not very good with constructing complex regular expressions.

It doesn't look like the Mod() would be usable in UEZ's routine, although I think getting rid of $t and ending this way might look prettier?

If $time < 12 Then
        $format = " am"
        If Not Mod($time, 12) Then $time = 12
    EndIf
    Return StringFormat("%02s:%02s:%02s %s", $time, $aToken[1], $aToken[2], $format)

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

@Spiff59: thanks for the optimization - I just modified something I wrote (look below) without looking twice to the function (I love your optimizations)!

;coded by UEZ 2011-04-10

$x = Convert24h(1, "pm")
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $x = ' & $x & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

$x = Convert2AMPM(18)
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $x = ' & $x & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

$x = Convert2AMPM2("00:59:00")
ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $x = ' & $x & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console

Func Convert24h($time, $format)
    If Not IsInt($time) Then Return SetError(1, 0, "Error!")
    If $time < 0  Or $time > 12 Then Return SetError(2, 0, "Error!")
    If $format <> "am" And $format <> "pm" Then Return SetError(3, 0, "Error!")
    If $format = "am" Then Return Mod($time, 12)
    Return Mod($time + 12, 24)
EndFunc

Func Convert2AMPM($time)
    If Not IsInt($time) Then Return SetError(1, 0, "Error!")
    If $time < 0  Or $time > 23 Then Return SetError(2, 0, "Error!")
    Local $format = " pm", $t
    If $time < 12 Then $format = " am"
    $t = Mod($time, 12)
    If Not $t Then Return 12 & $format
    Return $t & $format
EndFunc

Func Convert2AMPM2($time)
    Local $aToken = StringSplit($time, ":", 2)
    If Not IsArray($aToken) Then Return SetError(1, 0, "Error!")
    If UBound($aToken) <> 3 Then Return SetError(2, 0, "Error!")
    If $aToken[0] < 0 Or $aToken[0] > 23 Or $aToken[1] < 0 Or $aToken[1] > 59 Or $aToken[2] < 0 Or $aToken[2] > 59 Then Return SetError(3, 0, "Error!")
    $time = $aToken[0]
    If $time < 0  Or $time > 23 Then Return SetError(4, 0, "Error!")
    Local $format = " pm", $t
    If $time < 12 Then $format = " am"
    $t = Mod($time, 12)
    If Not $t Then $t = 12
    Return StringFormat("%02s:%02s:%02s %s", $t, $aToken[1], $aToken[2], $format)
EndFunc

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

#16 ·  Posted (edited)

@Spiff59, Thank you for your efforts.

However, if you added the modified code, for input of 12:00am,

If Not Mod($avDate[0], 12) Then $avDate[0] += 12 ; If 0 or 12 then add 12
$avDate[0]=24 at this point, then,
If $avDate[0] > 12 Then
        $avDate[0] -= 12
        $avDate[3] = "PM"
Else
This piece turns it to PM! and returns wrong results ;)

Don't feel bad though, if you read my posts above you would notice before I made it stable and packed it into a zip I was going through the bug motions myself, mostly 12:00 related too :)

EDIT: Spacing

Edited by smartee

Share this post


Link to post
Share on other sites

Hi all,

I have just requested if it's possible to add a 12/24 hour option to be returned since some or most of the date time function like _DateTimeFormat requires that the time format be in 24-hour. Hope to see this! Thanks a lot.

Share this post


Link to post
Share on other sites

...add a 12/24 hour option to be returned...

Done! ;)

Download it here: TimeValueUDFv1.2.zip

If this link is broken, PM me I will re-upload a copy. :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0