Checking and converting [[HH:]MM:]SS input format I would like to use the following routine in my job submission bash script which expects the allowed walltime in the format [[HH:]MM:]SS. (Brackets indicating optionality.) For easier readability I want to convert any input value into the fixed format HH:MM:SS where the value for hours is open ended.
I think it works okay, but I am a bit worried if I have overlooked possible points where a user could make a mistake. This could lead to submitting an invalid jobscript and a lot of computation jobs not starting.
I also ask myself whether or not my code is optimal.

#!/bin/bash

#
# If there is an unrecoverable error: display a message and exit.
#

printExit ()
{
    case $1 in
        [iI]) echo INFO: "$2" ;;
        [wW]) echo WARNING: "$2" ;;
        [eE]) echo ERROR: "$2" ; exit 1 ;;
           *) echo "$1" ;;
    esac
}

#
# Test if a given value is an integer
#

isnumeric ()
{
    if ! expr "$1" : '[[:digit:]]*$' &gt; /dev/null; then
        printExit E "Value for $2 ($1) is no integer."
    fi
}

#
# Test if a given value is a proper duration
#

istime ()
{
    local tempTime=$1
    # Split time in HH:MM:SS
    theTempSeconds=${tempTime##*:}
    isnumeric "$theTempSeconds" "seconds"
    if [[ ! "$tempTime" == "${tempTime%:*}" ]]; then
      tempTime="${tempTime%:*}"
      theTempMinutes=${tempTime##*:}
      isnumeric "$theTempMinutes" "minutes"
    fi
    if [[ ! "$tempTime" == "${tempTime%:*}" ]]; then
      tempTime="${tempTime%:*}"
      theTempHours=${tempTime##*:}
      isnumeric "$theTempHours" "hours"
    fi
    if [[ ! "$tempTime" == "${tempTime%:*}" ]]; then
      printExit E "Unrecognised format."
    fi

    theSeconds=`expr $theTempSeconds % 60`
    theTempMinutes=`expr $theTempMinutes + $theTempSeconds / 60`
    theMinutes=`expr $theTempMinutes % 60`
    theHours=`expr $theTempHours + $theTempMinutes / 60`

    printf -v theWalltime "%d:%02d:%02d" $theHours $theMinutes $theSeconds
}

theWalltime="$1"

echo "$theWalltime"

istime $theWalltime

echo "$theWalltime"

exit 0


I use the first two functions quite a lot in my script so I used them for the target function also.
Here are my suggestions:


The printExit() prints an error message, but does not exit.  It would be better to actually exit or rename the function.
Your regex in isnumeric() has two minor issues.  Putting a ^ at the beginning will make it clear that the regex matches the whole string.  While this is implicit with expr it does not fit with how most implementations work.  Another issue is that the * quantifier means 0 or more so it might match 0 or none of the what you're looking for.  So an empty string would match what you have since it would be zero digits followed by the end of the string.  I couldn't reproduce this failure mode, but I'd recommend this line instead which works for my tests:

if ! expr "$1" : '^[[:digit:]]\+$' &gt; /dev/null; then

It would be nice to explain what you're trying to do with those string manipulations with a few comments
More of your variables could be localized so they don't leak out of the function they are used in.
Using the in variable names to avoid conflicting with generic names works, but if you can find more descriptive names it would be easier to follow.  Along the same lines all variables are temporary so that doesn't help explain why the variable exists.  Maybe checkTime or even check_time.
All of the math is integer math.  You won't get any decimals with bash or expr math.  https://stackoverflow.com/questions/12722095/how-can-i-get-float-division explains that you can work around with bc.
Optimization Using expr is fine, but it calls an external program.  Using bash's builtin math would avoid spawning a new process and would cut out a lot of the script's time.
    ((just_minutes = just_minutes + trunc_seconds/60))