26
26
#include "timelib_private.h"
27
27
#include <math.h>
28
28
29
- timelib_rel_time * timelib_diff (timelib_time * one , timelib_time * two )
29
+ static void sort_old_to_new (timelib_time * * one , timelib_time * * two , timelib_rel_time * rt )
30
30
{
31
- timelib_rel_time * rt ;
32
31
timelib_time * swp ;
33
- timelib_sll dst_corr = 0 , dst_h_corr = 0 , dst_m_corr = 0 ;
34
- timelib_time_offset * trans = NULL ;
35
32
33
+ /* Check whether date/times need to be inverted. If both times are
34
+ * TIMELIB_ZONETYPE_ID times with the same TZID, we use the y-s + us fields. */
35
+ if (
36
+ (* one )-> zone_type == TIMELIB_ZONETYPE_ID &&
37
+ (* two )-> zone_type == TIMELIB_ZONETYPE_ID &&
38
+ (strcmp ((* one )-> tz_info -> name , (* two )-> tz_info -> name ) != 0 )
39
+ ) {
40
+ if (
41
+ ((* one )-> y > (* two )-> y ) ||
42
+ ((* one )-> y == (* two )-> y && (* one )-> m > (* two )-> m ) ||
43
+ ((* one )-> y == (* two )-> y && (* one )-> m == (* two )-> m && (* one )-> d > (* two )-> d ) ||
44
+ ((* one )-> y == (* two )-> y && (* one )-> m == (* two )-> m && (* one )-> d == (* two )-> d && (* one )-> h > (* two )-> h ) ||
45
+ ((* one )-> y == (* two )-> y && (* one )-> m == (* two )-> m && (* one )-> d == (* two )-> d && (* one )-> h == (* two )-> h && (* one )-> i > (* two )-> i ) ||
46
+ ((* 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
+ ((* 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
+ ) {
49
+ swp = * two ;
50
+ * two = * one ;
51
+ * one = swp ;
52
+ rt -> invert = 1 ;
53
+ }
54
+ return ;
55
+ }
36
56
37
- rt = timelib_rel_time_ctor ();
38
- rt -> invert = 0 ;
57
+ /* Fall back to using the SSE instead to rearrange */
39
58
if (
40
- (one -> sse > two -> sse ) ||
41
- (one -> sse == two -> sse && one -> us > two -> us )
59
+ (( * one ) -> sse > ( * two ) -> sse ) ||
60
+ (( * one ) -> sse == ( * two ) -> sse && ( * one ) -> us > ( * two ) -> us )
42
61
) {
43
- swp = two ;
44
- two = one ;
45
- one = swp ;
62
+ swp = * two ;
63
+ * two = * one ;
64
+ * one = swp ;
46
65
rt -> invert = 1 ;
47
66
}
67
+ }
68
+
69
+ timelib_rel_time * timelib_diff (timelib_time * one , timelib_time * two )
70
+ {
71
+ timelib_rel_time * rt ;
72
+ timelib_sll dst_corr = 0 , dst_h_corr = 0 , dst_m_corr = 0 ;
73
+ timelib_time_offset * trans = NULL ;
74
+
75
+ rt = timelib_rel_time_ctor ();
76
+ rt -> invert = 0 ;
77
+
78
+ sort_old_to_new (& one , & two , rt );
48
79
49
80
/* Calculate correction for UTC offset changes between first and second SSE */
50
81
dst_corr = two -> z - one -> z ;
@@ -64,7 +95,7 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two)
64
95
/* Fall Back: Cater for transition period, where rt->invert is 0, but there are negative numbers */
65
96
if (one -> dst == 1 && two -> dst == 0 ) {
66
97
/* First for two "Type 3" times */
67
- if (one -> zone_type == 3 && two -> zone_type == 3 ) {
98
+ if (one -> zone_type == TIMELIB_ZONETYPE_ID && two -> zone_type == TIMELIB_ZONETYPE_ID ) {
68
99
trans = timelib_get_time_zone_info (two -> sse , two -> tz_info );
69
100
if (trans ) {
70
101
if (one -> sse >= trans -> transition_time + dst_corr && one -> sse < trans -> transition_time ) {
@@ -89,8 +120,8 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two)
89
120
90
121
timelib_do_rel_normalize (rt -> invert ? one : two , rt );
91
122
92
- /* Do corrections for "Type 3" times */
93
- if (one -> zone_type == 3 && two -> zone_type == 3 && strcmp (one -> tz_info -> name , two -> tz_info -> name ) == 0 ) {
123
+ /* Do corrections for "Type 3" times with the same TZID */
124
+ if (one -> zone_type == TIMELIB_ZONETYPE_ID && two -> zone_type == TIMELIB_ZONETYPE_ID && strcmp (one -> tz_info -> name , two -> tz_info -> name ) == 0 ) {
94
125
if (one -> dst == 1 && two -> dst == 0 ) { /* Fall Back */
95
126
if (two -> tz_info ) {
96
127
trans = timelib_get_time_zone_info (two -> sse , two -> tz_info );
@@ -130,11 +161,16 @@ timelib_rel_time *timelib_diff(timelib_time *one, timelib_time *two)
130
161
}
131
162
} else {
132
163
/* Then for all the others */
133
- if (one -> zone_type == 3 && two -> zone_type == 3 ) {
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
+ ) {
134
169
rt -> h -= dst_h_corr ;
135
170
} else {
136
171
rt -> h -= dst_h_corr + (two -> dst - one -> dst );
137
172
}
173
+
138
174
rt -> i -= dst_m_corr ;
139
175
140
176
timelib_do_rel_normalize (rt -> invert ? one : two , rt );
0 commit comments