As an alternative, you could avoid bouncing through a nominal date and just use number and string manipulation:
select to_char(trunc(937/100), 'FM00') ||':'|| to_char(mod(937, 100), 'FM00') from dual;
TO_CHAR
-------
09:37
... though if your starting value is actually a string rather than a number there's another level of implicit conversion going on. (If it is a string you probably have bigger problems with validation, but the lpad
route might be the simplest way if you assume the data is always as expected).
With a range of values:
with t (n) as (
select 0 from dual
union all select 1 from dual
union all select 59 from dual
union all select 937 from dual
union all select 2300 from dual
union all select 2359 from dual
)
select n, to_char(trunc(n/100), 'FM00') ||':'|| to_char(mod(n, 100), 'FM00')
as integer_time
from t;
N INTEGER
---------- -------
0 00:00
1 00:01
59 00:59
937 09:37
2300 23:00
2359 23:59
If you don't want the leading zero - i.e. 937 instead of 09:37 - then change the first format model to FM90
.
If your data isn't constrained to be integers in the range 0-2359 then this would format 'bad' times, possibly with hashes for the hour part, while bouncing through a date would error. Neither is ideal, but hopefully is a moot point.