]> pd.if.org Git - pdclib/blob - functions/time/difftime.c
Using code from tzcode.
[pdclib] / functions / time / difftime.c
1 /* difftime( time_t, time_t )
2
3    This file is part of the Public Domain C Library (PDCLib).
4    Permission is granted to use, modify, and / or redistribute at will.
5 */
6
7 #include <time.h>
8
9 #ifndef REGTEST
10
11 double difftime( time_t time1, time_t time0 )
12 {
13     /* If we want to avoid rounding errors and overflows, we need to be
14        careful with the exact type of time_t being unknown to us.
15        The code below is based on tzcode's difftime.c, which is in the
16        public domain, so clarified as of 1996-06-05 by Arthur David Olson.
17     */
18
19     /* If double is large enough, simply covert and substract
20        (assuming that the larger type has more precision).
21     */
22     if ( sizeof( time_t ) < sizeof( double ) )
23     {
24         return (double)time1 - (double)time0;
25     }
26
27     /* The difference of two unsigned values cannot overflow if the
28        minuend is greater or equal to the subtrahend.
29     */
30     if ( ! _PDCLIB_TYPE_SIGNED( time_t ) )
31     {
32         return ( time1 >= time0 ) ? (double)( time1 - time0 ) : -(double)( time0 - time1 );
33     }
34
35     /* Use uintmax_t if wide enough. */
36     if ( sizeof( time_t ) <= sizeof( _PDCLIB_uintmax_t ) )
37     {
38         _PDCLIB_uintmax_t t1 = time1, t0 = time0;
39         return ( time1 >= time0 ) ? t1 - t0 : -(double)( t0 - t1 );
40     }
41
42     /* If both times have the same sign, their difference cannot overflow. */
43     if ( ( time1 < 0 ) == ( time0 < 0 ) )
44     {
45         return time1 - time0;
46     }
47
48     /* The times have opposite signs, and uintmax_t is too narrow.
49        This suffers from double rounding; attempt to lessen that
50        by using long double temporaries.
51     */
52     long double t1 = time1, t0 = time0;
53     return t1 - t0;
54 }
55
56 #endif
57
58 #ifdef TEST
59
60 #include "_PDCLIB_test.h"
61
62 int main( void )
63 {
64     TESTCASE( NO_TESTDRIVER );
65     return TEST_RESULTS;
66 }
67
68 #endif