Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate and Modify Time Input on the Fly

In Javascript, how can I validate and modify the user time input using the regular expression and string.replace function so that instead of telling the user anything, it will validate and modify the input on the fly?

For example, the user input could be 1.12p 13:12 1,12PM, but the final result should always be 1:12 PM.

Does anyone have examples on how to do so?

PS. I know that using timepicker is a way more efficient way, but I have to use the user input in this case

like image 594
Victor Avatar asked Nov 12 '22 19:11

Victor


1 Answers

A simple regex you could use as a starting point:

(\d{1,2})\s*[.,:;]\s*(\d{1,2})\s*(([Aa]|[Pp])[Mm]?)?
^        ^  ^     ^  ^        ^  ^ ^         ^
Hour group  |     |  Minutes  |  | |         M is optional
         |  Valid separators  |  | Case-insensitivity
         |        |           |  AM/PM group
         ------------------------------Allow spaces

You'd still need to validate that the time is valid (59:99 is probably not valid), but this would at least make it easier to parse the string in javascript. After you've parsed it, you can print it back out however you want.

EDIT: Oops. Forgot that javascript does not support named groups. Just use numbered groups to the same effect.

EXAMPLE
What the hay... here's a complete working example. When to validate (and what to do with invalid input) is left up to you:

<html>
    <head>
        <script>
function parseTime( timeString ){
    var timePattern = /(\d{1,2})\s*[.,:;]\s*(\d{1,2})\s*(([Aa]|[Pp])[Mm]?)?/;
    var timeMatch = timePattern.exec( timeString );

    var INVALID = null;

    if ( timeMatch !== null ){
        var hour = timeMatch[1];
        var minute = timeMatch[2];
        var ampm = timeMatch[3];

        if ( minute < 0 || minute > 59 )
            return INVALID;

        if ( ampm != "" ){
            if ( hour < 1 || hour > 12 )
                return INVALID;

            ampm = ampm.substring(0,1).toUpperCase() == "A" ? "AM" : "PM";
        } else {
            if ( hour > 23 )
                return INVALID;

            ampm = ( hour < 13 ? "AM" : "PM" );
            hour = hour % 12;
            if ( hour == 0 ) hour = 12;
        }

        return hour + ":" + minute + " " + ampm;
    } else {
        return INVALID;
    }
}

function unitTest(){
    var testStrings = [
        ["1:30 PM", "1:30 PM"],
        ["1.30p", "1:30 PM"],
        ["1;30a", "1:30 AM"],
        ["59:99 PM", null],
        ["0,30", "12:30 AM"],
        ["15:00", "3:00 PM"],
        ["abc", null] ];

    var testResults;
    testResults = "<table><tr><th>Input</th><th>Expected</th><th>Actual</th></tr>";

    for (var i = 0; i < testStrings.length; i++){
        testResults +=
            "<tr>" +
                "<td>" + testStrings[i][0] + "</td>" +
                "<td>" + testStrings[i][1] + "</td>" +
                "<td>" + parseTime( testStrings[i][0] ) + "</td>" +
                "<td>" + ( testStrings[i][1] == parseTime( testStrings[i][0] ) ?
                            "<span style='color:green'>Success</span>" :
                            "<span style='color:red'>Failure</span>" ) +
                "</td>" +
            "</tr>";
    }

    testResults += "</table>";

    this.document.getElementById("results").innerHTML = testResults;
}
        </script>
    </head>
    <body onload="unitTest();">

        <div id="results">
        </div>

    </body>
</html>

Output:

Input Expected Actual
1:30 PM 1:30 PM 1:30 PM Success
1.30p 1:30 PM 1:30 PM Success
1;30a 1:30 AM 1:30 AM Success
59:99 PM null null Success
0,30 12:30 AM 12:30 AM Success
15:00 3:00 PM 3:00 PM Success
abc null null Success

like image 50
JDB Avatar answered Nov 15 '22 08:11

JDB