Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Data Bases > Oracle Server > Re: how to coun...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 3 of 6 Topic 16528 of 17024
Post > Topic >>

Re: how to count elapsed time between sysdate and some saved

by "fitzjarrell@[EMAIL PROTECTED] " <oratune@[EMAIL PROTECTED] > May 7, 2008 at 12:52 PM

On May 7, 12:51=A0pm, sybra...@[EMAIL PROTECTED]
 wrote:
> On Wed, 7 May 2008 18:45:04 +0200, "buu" <a...@[EMAIL PROTECTED]
> wrote:
> >question is simple... I have an date field in an table and I would like
t=
o
> >measure time difference (minutes or sec.) between current time and that
> >field.
>
> >at wich way you propose?
>
> Assuming a non-paleolithic version of Oracle (I appreciate, you, as
> someone asking help, can't be bothered to post it, as you assume
> Oracle never changes), one would just subtract the two dates (the unit
> of a date is a day), so you get the difference expressed as a days
> fraction and feed that through the numtodsinterval function.
>
> --
> Sybrand Bakker
> Senior Oracle DBA

With many thanks to William Robertson for sharing this on his Oracle
WTF site.

<sarcasm>
Oh, but it's much more fun to make things complicated:

SQL> --
SQL> -- Let's build a package of convoluted
SQL> -- mathematical il-logic to return what
SQL> -- would normally be the result of a
SQL> -- simple subtraction of dates
SQL> --
SQL> --
SQL> -- You simply can't beat complexity
SQL> --
SQL> -- Many thanks to William Robertson
SQL> -- for bringing this exquisite example
SQL> -- to my attention and for providing
SQL> -- the table population code
SQL> --
SQL>
SQL> CREATE PACKAGE dates_pkg
  2  AS
  3  	 FUNCTION julian_date
  4  	     ( date_to_convert DATE )
  5  	     RETURN NUMBER;
  6
  7  	 FUNCTION minutes_since_midnight
  8  	     ( timevalue DATE )
  9  	     RETURN NUMBER;
 10
 11  	 FUNCTION minutes_elapsed
 12  	     ( lowdate DATE
 13  	     , highdate DATE )
 14  	     RETURN NUMBER;
 15
 16  END dates_pkg;
 17  /

Package created.

Elapsed: 00:00:00.01
SQL>
SQL> CREATE PACKAGE BODY dates_pkg
  2  AS
  3  	 FUNCTION julian_date
  4  	     ( date_to_convert DATE)
  5  	     RETURN NUMBER
  6  	 IS
  7  	     varch_value VARCHAR (10);
  8  	     num_value NUMBER (20);
  9  	 BEGIN
 10  	     --
 11  	     -- First, we take a date and convert it to a date by
converting it
 12  	     -- to a character string using the same format we will use
to
 13  	     -- convert it BACK to a date again
 14  	     --
 15  	     -- Oh, then we convert it back to a character string
 16  	     --
 17  	     -- In Julian format, which is a number
 18  	     --
 19  	     SELECT TO_CHAR
 20  		    ( TO_DATE(TO_CHAR(date_to_convert,'MM/DD/YYYY'),'MM/DD/
YYYY')
 21  		    , 'J')
 22  	     INTO   varch_value
 23  	     FROM   dual;
 24
 25  	     --
 26  	     -- Okay, so we had a Julian date as a number but we changed
it to
 27  	     -- a character string so we could go back and make it a ...
 28  	     -- NUMBER ... again
 29  	     --
 30  	     SELECT TO_NUMBER (varch_value)
 31  	     INTO   num_value
 32  	     FROM   dual;
 33
 34  	     --
 35  	     -- So, we finally make up our mind and keep it a number and
 36  	     -- return it from the function
 37  	     --
 38  	     RETURN (num_value);
 39  	 END julian_date;
 40
 41
 42  	 FUNCTION minutes_since_midnight (
 43  	     timevalue DATE)
 44  	     RETURN NUMBER
 45  	 IS
 46  	     secs_elapsed NUMBER (20);
 47  	     mins_elapsed NUMBER (20);
 48  	 BEGIN
 49  	     --
 50  	     -- So now we take a date and extract the time ****tion of
it,
 51  	     -- convert that BACK to a date, then convert THAT to a
string
 52  	     -- of seconds and convert THAT to a number
 53  	     --
 54  	     -- Is it me, or are we essentially driving across town just
to
 55  	     -- go next door?
 56  	     --
 57  	     SELECT TO_NUMBER
 58  		    ( TO_CHAR(TO_DATE(TO_CHAR(timevalue,'HH:MI AM'),'HH:MI AM')
 59  		    , 'SSSSS') )
 60  	     INTO   secs_elapsed
 61  	     FROM   dual;
 62
 63  	     --
 64  	     -- Oooo, now we divide that total number of seconds by ...
 65  	     -- wait for it ...
 66  	     -- any second now ...
 67  	     -- 60!  Who would have thought that 60 seconds equals
 68  	     -- one minute?
 69  	     --
 70  	     SELECT (secs_elapsed / 60)
 71  	     INTO   mins_elapsed
 72  	     FROM   dual;
 73
 74  	     --
 75  	     -- Before we rest on our laurels we return the minutes
since midnight
 76  	     --
 77  	     RETURN (mins_elapsed);
 78  	 END minutes_since_midnight;
 79
 80
 81  	 FUNCTION minutes_elapsed
 82  	     ( lowdate DATE
 83  	     , highdate DATE )
 84  	     RETURN NUMBER
 85  	 IS
 86  	     final_number NUMBER (20);
 87  	     low_julian NUMBER (20);
 88  	     high_julian NUMBER (20);
 89  	     num_days NUMBER (20);
 90  	     num_minutes NUMBER (20);
 91  	     temp_mins NUMBER (20);
 92  	     min_low NUMBER (20);
 93  	     min_high NUMBER (20);
 94  	 BEGIN
 95  	     --
 96  	     -- Now, why didn't we use this julian_date function in the
 97  	     -- last installment of Julian conversions?
 98  	     --
 99  	     -- Oh, yeah, because we just WROTE that wonderful function
100  	     --
101  	     -- So, okay, we take our date values and return the Julian
102  	     -- representations of them using all of the mathematical
103  	     -- aerobics from earlier
104  	     --
105  	     -- I guess this is so much easier than simply subtracting
106  	     -- them
107  	     --
108  	     SELECT julian_date (lowdate)
109  	     INTO   low_julian
110  	     FROM   dual;
111
112  	     SELECT julian_date (highdate)
113  	     INTO   high_julian
114  	     FROM   dual;
115
116  	     --
117  	     -- Woo-hoo! Higher math time!  Subtract the Julian dates
118  	     -- and get the number of days
119  	     --
120  	     -- Isn't that what we'd get if we just subtracted the
121  	     -- submitted dates as-is?
122  	     --
123  	     -- Of course it is
124  	     --
125  	     SELECT (high_julian - low_julian)
126  	     INTO   num_days
127  	     FROM   dual;
128
129  	     --
130  	     -- Now we calculate the total minutes elapsed
131  	     -- using our values generated by our extreme
132  	     -- gyrations
133  	     --
134  	     -- I'm out of breath just thinking about all of this work
135  	     --
136  	     SELECT (num_days * 1440)
137  	     INTO   num_minutes
138  	     FROM   dual;
139
140  	     --
141  	     -- And now we put those other mathematical moves
142  	     -- to use
143  	     --
144  	     -- Tell me again why we think we're smarter than
145  	     -- the average bear?
146  	     --
147  	     SELECT minutes_since_midnight (lowdate)
148  	     INTO   min_low
149  	     FROM   dual;
150
151  	     SELECT minutes_since_midnight (highdate)
152  	     INTO   min_high
153  	     FROM   dual;
154
155  	     --
156  	     -- Now this is disgusting
157  	     --
158  	     -- Using a TEMP variable to aid in simple mathematical
159  	     -- processing
160  	     --
161  	     SELECT (min_high - min_low)
162  	     INTO   temp_mins
163  	     FROM   dual;
164
165  	     --
166  	     -- And this is better than:
167  	     -- select (end_date - start_date)*1440 because?
168  	     --
169  	     SELECT (num_minutes + temp_mins)
170  	     INTO   final_number
171  	     FROM   dual;
172
173  	     RETURN (final_number);
174
175  	 END minutes_elapsed;
176  END dates_pkg;
177  /

Package body created.

Elapsed: 00:00:00.04
SQL>
SQL> --
SQL> -- This is more fun with a test table
SQL> --
SQL>
SQL> create table date_tst ( start_dt date, end_dt date);

Table created.

Elapsed: 00:00:00.01
SQL>
SQL> insert into date_tst
  2  select date '2006-12-25' + dbms_random.value(1,365)
  3  	  , date '2007-12-25' + dbms_random.value(1,365)
  4  FROM   dual connect by level <=3D 4000;

4000 rows created.

Elapsed: 00:00:00.15

SQL>
SQL> commit;

Commit complete.

Elapsed: 00:00:00.01
SQL>
SQL> --
SQL> --
SQL> -- Let's execute this mess
SQL> --
SQL> --
SQL>
SQL> set timing on autotrace traceonly
SQL>
SQL> select dates_pkg.minutes_elapsed(start_dt, end_dt) from date_tst;

4000 rows selected.

Elapsed: 00:00:03.01

Execution Plan
----------------------------------------------------------
Plan hash value: 2261420801

----------------------------------------------------------------------------=
--
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)|
Time     |
----------------------------------------------------------------------------=
--
|   0 | SELECT STATEMENT  |          |  4000 | 72000 |     5   (0)|
00:00:01 |
|   1 |  TABLE ACCESS FULL| DATE_TST |  4000 | 72000 |     5   (0)|
00:00:01 |
----------------------------------------------------------------------------=
--

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
      64014  recursive calls
          0  db block gets
        300  consistent gets
          0  physical reads
          0  redo size
      38634  bytes sent via SQL*Net to client
       2108  bytes received via SQL*Net from client
        268  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       4000  rows processed

SQL>
SQL> select (end_dt - start_dt)*1440 from date_tst;

4000 rows selected.

Elapsed: 00:00:00.21

Execution Plan
----------------------------------------------------------
Plan hash value: 2261420801

----------------------------------------------------------------------------=
--
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)|
Time     |
----------------------------------------------------------------------------=
--
|   0 | SELECT STATEMENT  |          |  4000 | 72000 |     5   (0)|
00:00:01 |
|   1 |  TABLE ACCESS FULL| DATE_TST |  4000 | 72000 |     5   (0)|
00:00:01 |
----------------------------------------------------------------------------=
--

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          4  recursive calls
          0  db block gets
        300  consistent gets
          0  physical reads
          0  redo size
     103258  bytes sent via SQL*Net to client
       2108  bytes received via SQL*Net from client
        268  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       4000  rows processed

SQL>
SQL> --
SQL> -- Let's hose up that last function
SQL> -- by passing the arguments in reverse
SQL> -- order
SQL> --
SQL> -- Maybe the original author should have
SQL> -- provided some parameter checking code
SQL> --
SQL>
SQL> select dates_pkg.minutes_elapsed(end_dt, start_dt) from date_tst;

4000 rows selected.

Elapsed: 00:00:03.04

Execution Plan
----------------------------------------------------------
Plan hash value: 2261420801

----------------------------------------------------------------------------=
--
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)|
Time     |
----------------------------------------------------------------------------=
--
|   0 | SELECT STATEMENT  |          |  4000 | 72000 |     5   (0)|
00:00:01 |
|   1 |  TABLE ACCESS FULL| DATE_TST |  4000 | 72000 |     5   (0)|
00:00:01 |
----------------------------------------------------------------------------=
--

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
      64004  recursive calls
          0  db block gets
        300  consistent gets
          0  physical reads
          0  redo size
      42634  bytes sent via SQL*Net to client
       2108  bytes received via SQL*Net from client
        268  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       4000  rows processed

SQL>
SQL> select (start_dt - end_dt)*1440 from date_tst;

4000 rows selected.

Elapsed: 00:00:00.23

Execution Plan
----------------------------------------------------------
Plan hash value: 2261420801

----------------------------------------------------------------------------=
--
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)|
Time     |
----------------------------------------------------------------------------=
--
|   0 | SELECT STATEMENT  |          |  4000 | 72000 |     5   (0)|
00:00:01 |
|   1 |  TABLE ACCESS FULL| DATE_TST |  4000 | 72000 |     5   (0)|
00:00:01 |
----------------------------------------------------------------------------=
--

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          4  recursive calls
          0  db block gets
        300  consistent gets
          0  physical reads
          0  redo size
     103470  bytes sent via SQL*Net to client
       2108  bytes received via SQL*Net from client
        268  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
       4000  rows processed

SQL>

There is nothing more satisfying than a job well done.

</sarcasm>

To be honest I can't understand why you don't use:

select (date2 -date1)*1440 from ...

to get the minutes between the two dates, or:

select (date2 - date1)*86400 from ...

to return the number of seconds between the dates.

Both have worked for years and continue to do so.


David Fitzjarrell
 




 6 Posts in Topic:
how to count elapsed time between sysdate and some saved timesta
"buu" <aha@[  2008-05-07 18:45:04 
Re: how to count elapsed time between sysdate and some saved tim
sybrandb@[EMAIL PROTECTED  2008-05-07 19:51:11 
Re: how to count elapsed time between sysdate and some saved
"fitzjarrell@[EMAIL   2008-05-07 12:52:06 
Re: how to count elapsed time between sysdate and some saved
Mark D Powell <Mark.Po  2008-05-07 13:08:27 
Re: how to count elapsed time between sysdate and some saved
"fitzjarrell@[EMAIL   2008-05-07 13:45:04 
Re: how to count elapsed time between sysdate and some saved
Mark D Powell <Mark.Po  2008-05-07 17:27:53 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Thu Aug 21 20:42:00 CDT 2008.