I’m not sure who originally wrote this function (probably Tom Kyte), but I needed it yesterday and couldn’t find it. Thankfully Chris Beck tracked it down in some other code I wrote. I made a few enhancements, but the bulk of the function is the same. The output is almost identical to the “SINCE” date format available in Application Express. So, if you pass in a date in the past to this function, the result will be similar to “25 seconds ago”, “1 minute ago”, “5 months ago”, etc.
Function
create or replace function date_text_format (p_date in date)
return varchar2
as
x varchar2(255);
begin
x := case
when sysdate-p_date < 1/1440
then round(24*60*60*(sysdate-p_date)) || ' seconds'
when sysdate-p_date < 1/24
then round(24*60*(sysdate-p_date)) || ' minutes'
when sysdate-p_date < 1
then round(24*(sysdate-p_date)) || ' hours'
when sysdate-p_date < 14
then trunc(sysdate-p_date) || ' days'
$IF $$BRITISH $THEN
when mod(trunc(sysdate-p_date),14) = 0
then trunc(sysdate-p_date) / 14 || ' fortnights'
$END
when sysdate-p_date < 60
then trunc((sysdate-p_date)/7) || ' weeks'
when sysdate-p_date < 365
then round(months_between(sysdate,p_date)) || ' months'
else round(months_between(sysdate,p_date)/12,1) || ' years'
end;
x:= regexp_replace(x,'(^1 [[:alnum:]]{4,10})s','\1');
x:= x || ' ago';
return x;
end date_text_format;
/
Examples
select date_text_format(sysdate - 3/86400) the_date from dual; select date_text_format(sysdate - 5/1440) the_date from dual; select date_text_format(sysdate - 1/24) the_date from dual; select date_text_format(sysdate - 3.141549) the_date from dual; select date_text_format(sysdate - 15) the_date from dual; select date_text_format(sysdate - 120) the_date from dual; select date_text_format(sysdate - 365) the_date from dual; -------------------------------------------------------------------- 3 seconds ago 5 minutes ago 1 hour ago 3 days ago 2 weeks ago 4 months ago 1 year ago