Oracle 9.2i / 10g: DateDiff als String in Monaten Tagen Stunden u.s.w ausgeben

planb2000

Erfahrenes Mitglied
Hallo,

heute haben wir folgedes diskutiert und keine AdHoc Lösung gefunden:

-- Berechne eine Zeitdifferenz aus zwei Datumsangaben
-- Gebe die Monate an
-- Gebe die Tage an
-- Gebe die Stunden an
-- Gebe die Minuten an

Beispiel:
SQL:
SELECT -- Monate extrahieren
 Trim (trailing '.' FROM RTrim (
                                months_between (to_date ('2006/06/01', 'yyyy/mm/dd'), to_date ('2006/03/03', 'yyyy/mm/dd'))
                                , '1234567890') 
 )monate 
       -- Tage extrahieren
,Trim (trailing '.' FROM RTrim (
                                30 * Ltrim (
                                months_between (to_date ('2006/06/01', 'yyyy/mm/dd'), to_date ('2006/03/03', 'yyyy/mm/dd'))
                                ,'1234567890' ) 
                         , '1234567890')) tage
       -- Stunden extrahieren
       -- ....
FROM dual

Ich merke gerade (1h) das dies echt nicht einfach ist und habe die Frage ob sich jemand damit schon mal befasst hat oder ob es eine Lösung von Oracle gibt.

Das Ergebnis dieser Berechnung stelle ich mir so vor:
SQL:
Die Differnz Ihrer Berechnung beträgt 2 Monate, 28 Tage, ... Stunden, ... Minuten

Kann jemand helfen?

Vielen Dank vorab
 
Zuletzt bearbeitet von einem Moderator:
Hilft dir das weiter?

SQL:
declare
   days            PLS_INTEGER;
   hours           PLS_INTEGER;
   minutes         PLS_INTEGER;
   seconds         PLS_INTEGER;

   end_date        DATE := TO_DATE('2006/06/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS');
   start_date      DATE := TO_DATE('2006/03/03 12:35:25', 'YYYY/MM/DD HH24:MI:SS');
begin

   SELECT  TRUNC(       end_date - start_date                   ),
           TRUNC( MOD( (end_date - start_date)*24,           24)),
           TRUNC( MOD( (end_date - start_date)*24 * 60,      60)),
           TRUNC( MOD( (end_date - start_date)*24 * 60 * 60, 60))
   INTO    days,
                   hours,
                   minutes,
                   seconds
   FROM    DUAL;

   DBMS_OUTPUT.put_line( 'days.....: ' || days );
   DBMS_OUTPUT.put_line( 'hours....: ' || hours );
   DBMS_OUTPUT.put_line( 'minutes..: ' || minutes );
   DBMS_OUTPUT.put_line( 'seconds..: ' || seconds );
end;
/
days.....: 89
hours....: 11
minutes..: 24
seconds..: 35

Thomas Kyte hat dazu übrigens eine ausführliche Beschreibung auf seiner Seite: http://asktom.oracle.com/tkyte/Misc/DateDiff.html

----
edit: Hab ganz übersehen dass du auch Monate braucht. Ich mach mich nochmal dran ... :)
 
Zuletzt bearbeitet von einem Moderator:
Wenn du von 30 Tagen pro Monat ausgehst, dann genügt eine kleine Anpassung am obigen Statement:

SQL:
SELECT  TRUNC(      (end_date - start_date)/30               ),
        TRUNC( MOD( (end_date - start_date),              30)),
        TRUNC( MOD( (end_date - start_date)*24,           24)),
        TRUNC( MOD( (end_date - start_date)*24 * 60,      60)),
        TRUNC( MOD( (end_date - start_date)*24 * 60 * 60, 60))
INTO    months,
        days,
        hours,
        minutes,
        seconds
FROM    DUAL;

months...: 2
days.....: 29
hours....: 11
minutes..: 24
seconds..: 35

Wenn du die Anzahl Tage der betroffenen Monate allerdings genau berücksichtigen möchtest, musst du anstatt der "(end_date - start_date)/30" die Funktion months_between einbauen. Bei der Berechnung der restilichen Tage wirds dann auch ein bisschen unschön. Prinzipiell würde ich bei der Darstellung Tage, Stunden, Minuten bleiben, das ist in jedem Fall eindeutig. Vielleicht eher auf Wochen gehen anstatt Monate.
 
Zuletzt bearbeitet von einem Moderator:
Hallo Exceptionfault,

vielen Dank für die Lösung. Mit der Unschärfe in der Monatsbetrachtung kann man erstmal leben.

Liebe Grüße
 

Neue Beiträge

Zurück