Skip to content

Commit 3559957

Browse files
committed
Fixed diff, again
1 parent 37d460b commit 3559957

File tree

4 files changed

+173
-127
lines changed

4 files changed

+173
-127
lines changed

ext/date/lib/interval.c

Lines changed: 69 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,37 @@
2626
#include "timelib_private.h"
2727
#include <math.h>
2828

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)
3030
{
3131
timelib_time *swp;
3232

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+
{
3360
/* Check whether date/times need to be inverted. If both times are
3461
* TIMELIB_ZONETYPE_ID times with the same TZID, we use the y-s + us fields. */
3562
if (
@@ -46,10 +73,7 @@ static void sort_old_to_new(timelib_time **one, timelib_time **two, timelib_rel_
4673
((*one)->y == (*two)->y && (*one)->m == (*two)->m && (*one)->d == (*two)->d && (*one)->h == (*two)->h && (*one)->i == (*two)->i && (*one)->s > (*two)->s) ||
4774
((*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)
4875
) {
49-
swp = *two;
50-
*two = *one;
51-
*one = swp;
52-
rt->invert = 1;
76+
swap_times(one, two, rt);
5377
}
5478
return;
5579
}
@@ -59,14 +83,11 @@ static void sort_old_to_new(timelib_time **one, timelib_time **two, timelib_rel_
5983
((*one)->sse > (*two)->sse) ||
6084
((*one)->sse == (*two)->sse && (*one)->us > (*two)->us)
6185
) {
62-
swp = *two;
63-
*two = *one;
64-
*one = swp;
65-
rt->invert = 1;
86+
swap_times(one, two, rt);
6687
}
6788
}
6889

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)
7091
{
7192
timelib_rel_time *rt;
7293
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)
98119
if (one->zone_type == TIMELIB_ZONETYPE_ID && two->zone_type == TIMELIB_ZONETYPE_ID) {
99120
trans = timelib_get_time_zone_info(two->sse, two->tz_info);
100121
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) {
102123
timelib_sll flipped = SECS_PER_HOUR + (rt->i * 60) + (rt->s);
103124
rt->h = flipped / SECS_PER_HOUR;
104125
rt->i = (flipped - rt->h * SECS_PER_HOUR) / 60;
@@ -160,19 +181,11 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two)
160181
}
161182
}
162183
} 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;
174185
rt->i -= dst_m_corr;
175186

187+
swap_if_negative(rt);
188+
176189
timelib_do_rel_normalize(rt->invert ? one : two, rt);
177190
}
178191

@@ -183,6 +196,40 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two)
183196
return rt;
184197
}
185198

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+
186233

187234
int timelib_diff_days(timelib_time *one, timelib_time *two)
188235
{

0 commit comments

Comments
 (0)