26
26
#include "timelib_private.h"
27
27
#include <math.h>
28
28
29
- static void sort_old_to_new (timelib_time * * one , timelib_time * * two , timelib_rel_time * rt )
29
+ static void swap_times (timelib_time * * one , timelib_time * * two , timelib_rel_time * rt )
30
30
{
31
31
timelib_time * swp ;
32
32
33
+ swp = * two ;
34
+ * two = * one ;
35
+ * one = swp ;
36
+ rt -> invert = 1 ;
37
+ }
38
+
39
+ static void swap_if_negative (timelib_rel_time * rt )
40
+ {
41
+ if (rt -> y == 0 && rt -> m == 0 && rt -> d == 0 && rt -> h == 0 && rt -> i == 0 && rt -> s == 0 && rt -> us == 0 ) {
42
+ return ;
43
+ }
44
+ if (rt -> y >= 0 && rt -> m >= 0 && rt -> d >= 0 && rt -> h >= 0 && rt -> i >= 0 && rt -> s >= 0 && rt -> us >= 0 ) {
45
+ return ;
46
+ }
47
+
48
+ rt -> invert = 1 - rt -> invert ;
49
+ rt -> y = 0 - rt -> y ;
50
+ rt -> m = 0 - rt -> m ;
51
+ rt -> d = 0 - rt -> d ;
52
+ rt -> h = 0 - rt -> h ;
53
+ rt -> i = 0 - rt -> i ;
54
+ rt -> s = 0 - rt -> s ;
55
+ rt -> us = 0 - rt -> us ;
56
+ }
57
+
58
+ static void sort_old_to_new (timelib_time * * one , timelib_time * * two , timelib_rel_time * rt )
59
+ {
33
60
/* Check whether date/times need to be inverted. If both times are
34
61
* TIMELIB_ZONETYPE_ID times with the same TZID, we use the y-s + us fields. */
35
62
if (
@@ -46,10 +73,7 @@ static void sort_old_to_new(timelib_time **one, timelib_time **two, timelib_rel_
46
73
((* one )-> y == (* two )-> y && (* one )-> m == (* two )-> m && (* one )-> d == (* two )-> d && (* one )-> h == (* two )-> h && (* one )-> i == (* two )-> i && (* one )-> s > (* two )-> s ) ||
47
74
((* one )-> y == (* two )-> y && (* one )-> m == (* two )-> m && (* one )-> d == (* two )-> d && (* one )-> h == (* two )-> h && (* one )-> i == (* two )-> i && (* one )-> s == (* two )-> s && (* one )-> us > (* two )-> us )
48
75
) {
49
- swp = * two ;
50
- * two = * one ;
51
- * one = swp ;
52
- rt -> invert = 1 ;
76
+ swap_times (one , two , rt );
53
77
}
54
78
return ;
55
79
}
@@ -59,14 +83,11 @@ static void sort_old_to_new(timelib_time **one, timelib_time **two, timelib_rel_
59
83
((* one )-> sse > (* two )-> sse ) ||
60
84
((* one )-> sse == (* two )-> sse && (* one )-> us > (* two )-> us )
61
85
) {
62
- swp = * two ;
63
- * two = * one ;
64
- * one = swp ;
65
- rt -> invert = 1 ;
86
+ swap_times (one , two , rt );
66
87
}
67
88
}
68
89
69
- timelib_rel_time * timelib_diff (timelib_time * one , timelib_time * two )
90
+ static timelib_rel_time * timelib_diff_with_tzid (timelib_time * one , timelib_time * two )
70
91
{
71
92
timelib_rel_time * rt ;
72
93
timelib_sll dst_corr = 0 , dst_h_corr = 0 , dst_m_corr = 0 ;
@@ -98,7 +119,7 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two)
98
119
if (one -> zone_type == TIMELIB_ZONETYPE_ID && two -> zone_type == TIMELIB_ZONETYPE_ID ) {
99
120
trans = timelib_get_time_zone_info (two -> sse , two -> tz_info );
100
121
if (trans ) {
101
- if (one -> sse >= trans -> transition_time + dst_corr && one -> sse < trans -> transition_time ) {
122
+ if (one -> sse < trans -> transition_time && one -> sse >= trans -> transition_time + dst_corr ) {
102
123
timelib_sll flipped = SECS_PER_HOUR + (rt -> i * 60 ) + (rt -> s );
103
124
rt -> h = flipped / SECS_PER_HOUR ;
104
125
rt -> i = (flipped - rt -> h * SECS_PER_HOUR ) / 60 ;
@@ -160,19 +181,11 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two)
160
181
}
161
182
}
162
183
} else {
163
- /* Then for all the others */
164
- if (
165
- (one -> zone_type == 3 && two -> zone_type == 3 ) ||
166
- (one -> zone_type != 3 && two -> zone_type == 3 && one -> z == two -> z ) ||
167
- (one -> zone_type == 3 && two -> zone_type != 3 && one -> z == two -> z )
168
- ) {
169
- rt -> h -= dst_h_corr ;
170
- } else {
171
- rt -> h -= dst_h_corr + (two -> dst - one -> dst );
172
- }
173
-
184
+ rt -> h -= dst_h_corr ;
174
185
rt -> i -= dst_m_corr ;
175
186
187
+ swap_if_negative (rt );
188
+
176
189
timelib_do_rel_normalize (rt -> invert ? one : two , rt );
177
190
}
178
191
@@ -183,6 +196,40 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two)
183
196
return rt ;
184
197
}
185
198
199
+ timelib_rel_time * timelib_diff (timelib_time * one , timelib_time * two )
200
+ {
201
+ timelib_rel_time * rt ;
202
+
203
+ if (one -> zone_type == TIMELIB_ZONETYPE_ID && two -> zone_type == TIMELIB_ZONETYPE_ID ) {
204
+ return timelib_diff_with_tzid (one , two );
205
+ }
206
+
207
+ rt = timelib_rel_time_ctor ();
208
+ rt -> invert = 0 ;
209
+
210
+ sort_old_to_new (& one , & two , rt );
211
+
212
+ rt -> y = two -> y - one -> y ;
213
+ rt -> m = two -> m - one -> m ;
214
+ rt -> d = two -> d - one -> d ;
215
+ rt -> h = two -> h - one -> h ;
216
+ if (one -> zone_type != TIMELIB_ZONETYPE_ID ) {
217
+ rt -> h = rt -> h + one -> dst ;
218
+ }
219
+ if (two -> zone_type != TIMELIB_ZONETYPE_ID ) {
220
+ rt -> h = rt -> h - two -> dst ;
221
+ }
222
+ rt -> i = two -> i - one -> i ;
223
+ rt -> s = two -> s - one -> s - two -> z + one -> z ;
224
+ rt -> us = two -> us - one -> us ;
225
+
226
+ rt -> days = timelib_diff_days (one , two );
227
+
228
+ timelib_do_rel_normalize (rt -> invert ? one : two , rt );
229
+
230
+ return rt ;
231
+ }
232
+
186
233
187
234
int timelib_diff_days (timelib_time * one , timelib_time * two )
188
235
{
0 commit comments