*! 1.0.0 NJC 31 January 2006 program stimeofday, rclass version 8 syntax varlist(num) [if] [in], /// String(str) Numeric(str) Generate(str) /// [ * TIMEonly am(str) pm(str) /// DFormat(str) HFormat(str) MFormat(str) SFormat(str) /// DSymbol(str) HSymbol(str) MSymbol(str) SSymbol(str) ] // check numeric() and string() // either could say nothing: unlikely, but check if trim("`numeric'") == "" { di as err "invalid numeric() option" exit 198 } if trim("`string'") == "" { di as err "invalid string() option" exit 198 } // numeric() has to signal one of days hours hrs minutes seconds local numeric = lower(trim("`numeric'")) local len = length("`numeric'") foreach ok in days hours hrs minutes seconds { if "`numeric'" == substr("`ok'",1,`len') { local unit = cond("`ok'" == "hrs", "hours", "`ok'") } } if "`unit'" == "" { di as err /// "numeric() option should specify one of days, hours, minutes, seconds" exit 198 } // string() may signal days hours hrs minutes seconds foreach s of local string { local s = lower("`s'") local len = length("`s'") foreach ok in days hours hrs minutes seconds { if "`s'" == substr("`ok'",1,`len') { local String `String' `ok' } } } // no duplicates allowed, and every component must be valid local String : subinstr local String "hrs" "hours" local String : list uniq String if `: word count `string'' != `: word count `String'' { di as err "invalid string() option" exit 198 } // valid d h m s, d h m, d h, h m s, h m, m s local list1 days hours minutes seconds local list2 days hours minutes local list3 days hours local list4 hours minutes seconds local list5 hours minutes local list6 minutes seconds forval i = 1/6 { local istype : list String == list`i' if `istype' local listtype `i' } if "`listtype'" == "" { di as err "string() option invalid" exit 198 } if "`timeonly'" != "" & `listtype' < 4 { di as err "timeonly and string(`string') not compatible" exit 198 } if "`am'`pm'" != "" { if inlist(`listtype', 3, 6) { di as err "am/pm and string(`string') not compatible" exit 198 } tempvar ispm gen byte `ispm' = . } // process varlist tokenize `varlist' local nvars : word count `varlist' local oldvarlist "`varlist'" // do before second -syntax- marksample touse, novarlist qui count if `touse' if r(N) == 0 error 2000 // new varlist valid? local 0 "`generate'" syntax newvarlist // do existing and new varlists match one-to-one? if `nvars' != `: word count `varlist'' { di as err "number of new variables not equal to" _c di as err " number of existing variables" exit 198 } // day, hour, min, second formats if "`dformat'" != "" local dformat `", "`dformat'" "' if "`hformat'" == "" local hformat "%02.0f" if "`mformat'" == "" local mformat "%02.0f" if "`sformat'" == "" local sformat "%05.2f" // day, hour, min symbols if `"`dsymbol'"' == "" local dsymbol " " if `"`hsymbol'"' == "" & `listtype' != 3 local hsymbol ":" if `"`msymbol'"' == "" & !inlist(`listtype', 2, 5) local msymbol ":" // `ssymbol' defaults to empty string // initialise tempvar rest gen double `rest' = 0 if "`unit'" == "days" { quietly forval i = 1 / `nvars' { tempvar work touse2 // markout separately for each variable gen byte `touse2' = `touse' markout `touse2' ``i'' gen `work' = "" if "`am'`pm'" != "" replace `ispm' = `touse2' local I "``i''" if "`timeonly'" != "" { replace `rest' = ``i'' - floor(``i'') local `i' "`rest'" } if `listtype' == 1 { replace `work' = string(floor(``i'') `dformat') + `"`dsymbol'"' replace `rest' = ``i'' - floor(``i'') if "`am'`pm'" != "" { replace `ispm' = `ispm' * (24 * `rest' >= 13) replace `rest' = `rest' - 0.5 if `ispm' } replace `work' = `work' + string(floor(24 * `rest'), "`hformat'") + `"`hsymbol'"' replace `rest' = mod(24 * `rest', 1) replace `work' = `work' + string(floor(60 * `rest'), "`mformat'") + `"`msymbol'"' replace `rest' = mod(60 * `rest', 1) replace `work' = `work' + string(60 * `rest', "`sformat'") + `"`ssymbol'"' } else if `listtype' == 2 { replace `work' = string(floor(``i'') `dformat') + `"`dsymbol'"' replace `rest' = ``i'' - floor(``i'') if "`am'`pm'" != "" { replace `ispm' = `ispm' * (24 * `rest' >= 13) replace `rest' = `rest' - 0.5 if `ispm' } replace `work' = `work' + string(floor(24 * `rest'), "`hformat'") + `"`hsymbol'"' replace `rest' = mod(24 * `rest', 1) replace `work' = `work' + string(60 * `rest', "`mformat'") + `"`msymbol'"' } else if `listtype' == 3 { replace `work' = string(floor(``i'') `dformat') + `"`dsymbol'"' replace `rest' = ``i'' - floor(``i'') replace `work' = `work' + string(24 * `rest', "`hformat'") + `"`hsymbol'"' } else if `listtype' == 4 { replace `rest' = 24 * ``i'' if "`am'`pm'" != "" { capture assert `rest' < 24 if `touse2' if _rc { di as err "24 hours or more in `I' not compatible with am/pm" exit 498 } replace `ispm' = `ispm' * (`rest' >= 13) replace `rest' = `rest' - 12 if `ispm' } replace `work' = string(floor(`rest'), "`hformat'") + `"`hsymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(floor(`rest'), "`mformat'") + `"`msymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(`rest', "`sformat'") + `"`ssymbol'"' } else if `listtype' == 5 { replace `rest' = 24 * ``i'' if "`am'`pm'" != "" { capture assert `rest' < 24 if `touse2' if _rc { di as err "24 hours or more in `I' not compatible with am/pm" exit 498 } replace `ispm' = `ispm' * (`rest' >= 13) replace `rest' = `rest' - 12 if `ispm' } replace `work' = string(floor(`rest'), "`hformat'") + `"`hsymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(`rest', "`mformat'") + `"`msymbol'"' } else if `listtype' == 6 { replace `rest' = 1440 * ``i'' replace `work' = string(floor(`rest'), "`mformat'") + `"`msymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(`rest', "`sformat'") + `"`ssymbol'"' } replace `work' = "" if `touse2' == 0 if "`am'`pm'" != "" { replace `work' = `work' + cond(`ispm', "`pm'", "`am'") } local togenerate "`togenerate' `work'" } } else if "`unit'" == "hours" { quietly forval i = 1 / `nvars' { tempvar work touse2 // markout separately for each variable gen byte `touse2' = `touse' markout `touse2' ``i'' gen `work' = "" if "`am'`pm'" != "" replace `ispm' = `touse2' local I "``i''" if "`timeonly'" != "" { replace `rest' = mod(``i'', 24) local `i' "`rest'" } if `listtype' == 1 { replace `work' = string(floor(``i'' / 24) `dformat') + `"`dsymbol'"' replace `rest' = mod(``i'', 24) if "`am'`pm'" != "" { replace `ispm' = `ispm' * (`rest' >= 13) replace `rest' = `rest' - 12 if `ispm' } replace `work' = `work' + string(floor(`rest'), "`hformat'") + `"`hsymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(floor(`rest'), "`mformat'") + `"`msymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(`rest', "`sformat'") + `"`ssymbol'"' } else if `listtype' == 2 { replace `work' = string(floor(``i'' / 24) `dformat') + `"`dsymbol'"' replace `rest' = mod(``i'', 24) if "`am'`pm'" != "" { replace `ispm' = `ispm' * (`rest' >= 13) replace `rest' = `rest' - 12 if `ispm' } replace `work' = `work' + string(floor(`rest'), "`hformat'") + `"`hsymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(`rest', "`mformat'") + `"`msymbol'"' } else if `listtype' == 3 { replace `work' = string(floor(``i'' / 24) `dformat') + `"`dsymbol'"' replace `rest' = mod(``i'', 24) replace `work' = `work' + string(`rest', "`hformat'") + `"`hsymbol'"' } else if `listtype' == 4 { replace `rest' = ``i'' if "`am'`pm'" != "" { capture assert `rest' < 24 if `touse2' if _rc { di as err "24 hours or more in `I' not compatible with am/pm" exit 498 } replace `ispm' = `ispm' * (`rest' >= 13) replace `rest' = `rest' - 12 if `ispm' } replace `work' = string(floor(`rest'), "`hformat'") + `"`hsymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(floor(`rest'), "`mformat'") + `"`msymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(`rest', "`sformat'") + `"`ssymbol'"' } else if `listtype' == 5 { replace `rest' = ``i'' if "`am'`pm'" != "" { capture assert `rest' < 24 if `touse2' if _rc { di as err "24 hours or more in `I' not compatible with am/pm" exit 498 } replace `ispm' = `ispm' * (`rest' >= 13) replace `rest' = `rest' - 12 if `ispm' } replace `work' = string(floor(`rest'), "`hformat'") + `"`hsymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(`rest', "`mformat'") + `"`msymbol'"' } else if `listtype' == 6 { replace `rest' = 60 * ``i'' replace `work' = string(floor(`rest'), "`mformat'") + `"`msymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(`rest', "`sformat'") + `"`ssymbol'"' } replace `work' = "" if `touse2' == 0 if "`am'`pm'" != "" { replace `work' = `work' + cond(`ispm', "`pm'", "`am'") } local togenerate "`togenerate' `work'" } } else if "`unit'" == "minutes" { quietly forval i = 1 / `nvars' { tempvar work touse2 // markout separately for each variable gen byte `touse2' = `touse' markout `touse2' ``i'' gen `work' = "" if "`am'`pm'" != "" replace `ispm' = `touse2' local I "``i''" if "`timeonly'" != "" { replace `rest' = mod(``i'', 1440) local `i' "`rest'" } if `listtype' == 1 { replace `work' = string(floor(``i'' / 1440) `dformat') + `"`dsymbol'"' replace `rest' = mod(``i'', 1440) if "`am'`pm'" != "" { replace `ispm' = `ispm' * (`rest' >= 780) replace `rest' = `rest' - 720 if `ispm' } replace `work' = `work' + string(floor(`rest' / 60), "`hformat'") + `"`hsymbol'"' replace `rest' = mod(`rest', 60) replace `work' = `work' + string(floor(`rest'), "`mformat'") + `"`msymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(`rest', "`sformat'") + `"`ssymbol'"' } else if `listtype' == 2 { replace `work' = string(floor(``i'' / 1440) `dformat') + `"`dsymbol'"' replace `rest' = mod(``i'', 1440) if "`am'`pm'" != "" { replace `ispm' = `ispm' * (`rest' >= 780) replace `rest' = `rest' - 720 if `ispm' } replace `work' = `work' + string(floor(`rest' / 60), "`hformat'") + `"`hsymbol'"' replace `rest' = mod(`rest', 60) replace `work' = `work' + string(`rest', "`mformat'") + `"`msymbol'"' } else if `listtype' == 3 { replace `work' = string(floor(``i'' / 1440) `dformat') + `"`dsymbol'"' replace `rest' = mod(``i'', 1440) replace `work' = `work' + string(`rest' / 60, "`hformat'") + `"`hsymbol'"' } else if `listtype' == 4 { replace `rest' = ``i'' / 60 if "`am'`pm'" != "" { capture assert `rest' < 24 if `touse2' if _rc { di as err "24 hours or more in `I' not compatible with am/pm" exit 498 } replace `ispm' = `ispm' * (`rest' >= 13) replace `rest' = `rest' - 12 if `ispm' } replace `work' = string(floor(`rest'), "`hformat'") + `"`hsymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(floor(`rest'), "`mformat'") + `"`msymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(`rest', "`sformat'") + `"`ssymbol'"' } else if `listtype' == 5 { replace `rest' = ``i'' / 60 if "`am'`pm'" != "" { capture assert `rest' < 24 if `touse2' if _rc { di as err "24 hours or more in `I' not compatible with am/pm" exit 498 } replace `ispm' = `ispm' * (`rest' >= 13) replace `rest' = `rest' - 12 if `ispm' } replace `work' = string(floor(`rest'), "`hformat'") + `"`hsymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(`rest', "`mformat'") + `"`msymbol'"' } else if `listtype' == 6 { replace `work' = string(floor(``i''), "`mformat'") + `"`msymbol'"' replace `rest' = 60 * mod(``i'', 1) replace `work' = `work' + string(`rest', "`sformat'") + `"`ssymbol'"' } replace `work' = "" if `touse2' == 0 if "`am'`pm'" != "" { replace `work' = `work' + cond(`ispm', "`pm'", "`am'") } local togenerate "`togenerate' `work'" } } else if "`unit'" == "seconds" { quietly forval i = 1 / `nvars' { tempvar work touse2 // markout separately for each variable gen byte `touse2' = `touse' markout `touse2' ``i'' gen `work' = "" if "`am'`pm'" != "" replace `ispm' = `touse2' local I "``i''" if "`timeonly'" != "" { replace `work' = mod(``i'', 86400) local `i' "`rest'" } if `listtype' == 1 { replace `work' = string(floor(``i'' / 86400) `dformat') + `"`dsymbol'"' replace `rest' = mod(``i'', 86400) if "`am'`pm'" != "" { replace `ispm' = `ispm' * (`rest' >= 46800) replace `rest' = `rest' - 43200 if `ispm' } replace `work' = `work' + string(floor(`rest' / 3600), "`hformat'") + `"`hsymbol'"' replace `rest' = mod(`rest', 3600) replace `work' = `work' + string(floor(`rest' / 60), "`mformat'") + `"`msymbol'"' replace `rest' = mod(`rest', 60) replace `work' = `work' + string(`rest', "`sformat'") + `"`ssymbol'"' } else if `listtype' == 2 { replace `work' = string(floor(``i'' / 86400) `dformat') + `"`dsymbol'"' replace `rest' = mod(``i'', 86400) if "`am'`pm'" != "" { replace `ispm' = `ispm' * (`rest' >= 46800) replace `rest' = `rest' - 43200 if `ispm' } replace `work' = `work' + string(floor(`rest' / 3600), "`hformat'") + `"`hsymbol'"' replace `rest' = mod(`rest', 3600) / 60 replace `work' = `work' + string(`rest', "`mformat'") + `"`msymbol'"' } else if `listtype' == 3 { replace `work' = string(floor(``i'' / 86400) `dformat') + `"`dsymbol'"' replace `rest' = mod(``i'', 86400) / 3600 replace `work' = `work' + string(`rest', "`hformat'") + `"`hsymbol'"' } else if `listtype' == 4 { replace `rest' = ``i'' / 3600 if "`am'`pm'" != "" { capture assert `rest' < 24 if `touse2' if _rc { di as err "24 hours or more in `I' not compatible with am/pm" exit 498 } replace `ispm' = `ispm' * (`rest' >= 13) replace `rest' = `rest' - 12 if `ispm' } replace `work' = string(floor(`rest'), "`hformat'") + `"`hsymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(floor(`rest'), "`mformat'") + `"`msymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(`rest', "`sformat'") + `"`ssymbol'"' } else if `listtype' == 5 { replace `rest' = ``i'' / 3600 if "`am'`pm'" != "" { capture assert `rest' < 24 if `touse2' if _rc { di as err "24 hours or more in `I' not compatible with am/pm" exit 498 } replace `ispm' = `ispm' * (`rest' >= 13) replace `rest' = `rest' - 12 if `ispm' } replace `work' = string(floor(`rest'), "`hformat'") + `"`hsymbol'"' replace `rest' = 60 * mod(`rest', 1) replace `work' = `work' + string(`rest', "`mformat'") + `"`msymbol'"' } else if `listtype' == 6 { replace `work' = string(floor(``i'' / 60), "`mformat'") + `"`msymbol'"' replace `rest' = mod(``i'', 60) replace `work' = `work' + string(`rest', "`sformat'") + `"`ssymbol'"' } replace `work' = "" if `touse2' == 0 if "`am'`pm'" != "" { replace `work' = `work' + cond(`ispm', "`pm'", "`am'") } local togenerate "`togenerate' `work'" } } // generate new variables iff all are OK tokenize "`togenerate'" local i = 1 quietly { foreach v of local varlist { gen `v' = ``i'' local V : word `i' of `oldvarlist' label var `v' "`V' (`String')" local ++i } } d `varlist' return local varlist "`varlist'" end