program define mkfrac /* newvar oldvar */
        version 5.0
        local newvar "`1'"
        local oldvar "`2'"

        confirm string variable `oldvar'

        tempvar copy ispm result
        quietly {
                gen str40 `copy' = trim(lower(`oldvar'))
                compress `copy'

                gen byte `ispm' = 0
                DoSuffix `copy' `ispm'

                capture assert index(`copy',":")==0
                if _rc {
                        DoColon `result' `copy'
                }
                else    DoPos `result' `copy'

                replace `result' = `result'/24 + .5*`ispm'
                replace `result' = . if `result'>1 | `result'<0
        }
        rename `result' `newvar'
end

program define DoSuffix
        local copy "`1'"
        local ispm "`2'"

        Suffix `copy' `ispm' "a.m." 0
        Suffix `copy' `ispm' "am" 0
        Suffix `copy' `ispm' "p.m." 1
        Suffix `copy' `ispm' "pm" 1
end

program define Suffix
        local copy "`1'"
        local ispm "`2'"
        local suffix "`3'"
        local marker "`4'"

        local l = length("`suffix'")

        tempvar hassfx
        quietly {
                gen byte `hassfx' = substr(`copy',-`l',.) == "`suffix'"
                replace `ispm' = `marker' if `hassfx'
                replace `copy' = trim(substr(`copy',1,length(`copy')-`l')) /*
                                */ if `hassfx'
        }
end


program define DoColon /* newvar copy */
        local newvar "`1'"
        local copy "`2'"

        tempvar l
        quietly {
                gen byte `l' = index(`copy',":")
                gen double `newvar' = real(substr(`copy',1,`l'-1)) if `l'
                replace `copy' = substr(`copy',`l'+1,.) if `l'
                replace `l' = index(`copy',":")
                replace `newvar' = `newvar' + real(`copy')/60 if `l'==0
                replace `newvar' = `newvar' + /*
                        */ real(substr(`copy',1,`l'-1))/60 + /*
                        */ real(substr(`copy',`l'+1,.))/(60*60) if `l'
        }
end

program define DoPos /* newvar copy */
        local newvar "`1'"
        local copy "`2'"

        tempvar l
        quietly {
                gen byte `l' = lengh(`copy')
                gen double `newvar' = real(substr(`copy',1,2)) + /*
                        */ real(substr(`copy',3,2))/60 if `l'==4 | `l'==6
                replace `newvar' = `newvar' + /*
                        */ real(substr(`copy',5,2)) if `l'==6
        }
end
exit