1use crate::Dt;
8
9pub struct LeapSecond {
10 pub ntp_timestamp: i64,
11 pub leap_seconds_after: i64,
12 pub utc_sec: i64,
13 pub tai_sec: i64,
14}
15
16pub const LEAP_SECS: &[LeapSecond] = &[
17 LeapSecond {
18 ntp_timestamp: 2272060800,
19 leap_seconds_after: 10,
20 utc_sec: -883656000,
21 tai_sec: -883655991, }, LeapSecond {
24 ntp_timestamp: 2287785600,
25 leap_seconds_after: 11,
26 utc_sec: -867931200,
27 tai_sec: -867931190, }, LeapSecond {
30 ntp_timestamp: 2303683200,
31 leap_seconds_after: 12,
32 utc_sec: -852033600,
33 tai_sec: -852033589, }, LeapSecond {
36 ntp_timestamp: 2335219200,
37 leap_seconds_after: 13,
38 utc_sec: -820497600,
39 tai_sec: -820497588, }, LeapSecond {
42 ntp_timestamp: 2366755200,
43 leap_seconds_after: 14,
44 utc_sec: -788961600,
45 tai_sec: -788961587, }, LeapSecond {
48 ntp_timestamp: 2398291200,
49 leap_seconds_after: 15,
50 utc_sec: -757425600,
51 tai_sec: -757425586, }, LeapSecond {
54 ntp_timestamp: 2429913600,
55 leap_seconds_after: 16,
56 utc_sec: -725803200,
57 tai_sec: -725803185, }, LeapSecond {
60 ntp_timestamp: 2461449600,
61 leap_seconds_after: 17,
62 utc_sec: -694267200,
63 tai_sec: -694267184, }, LeapSecond {
66 ntp_timestamp: 2492985600,
67 leap_seconds_after: 18,
68 utc_sec: -662731200,
69 tai_sec: -662731183, }, LeapSecond {
72 ntp_timestamp: 2524521600,
73 leap_seconds_after: 19,
74 utc_sec: -631195200,
75 tai_sec: -631195182, }, LeapSecond {
78 ntp_timestamp: 2571782400,
79 leap_seconds_after: 20,
80 utc_sec: -583934400,
81 tai_sec: -583934381, }, LeapSecond {
84 ntp_timestamp: 2603318400,
85 leap_seconds_after: 21,
86 utc_sec: -552398400,
87 tai_sec: -552398380, }, LeapSecond {
90 ntp_timestamp: 2634854400,
91 leap_seconds_after: 22,
92 utc_sec: -520862400,
93 tai_sec: -520862379, }, LeapSecond {
96 ntp_timestamp: 2698012800,
97 leap_seconds_after: 23,
98 utc_sec: -457704000,
99 tai_sec: -457703978, }, LeapSecond {
102 ntp_timestamp: 2776982400,
103 leap_seconds_after: 24,
104 utc_sec: -378734400,
105 tai_sec: -378734377, }, LeapSecond {
108 ntp_timestamp: 2840140800,
109 leap_seconds_after: 25,
110 utc_sec: -315576000,
111 tai_sec: -315575976, }, LeapSecond {
114 ntp_timestamp: 2871676800,
115 leap_seconds_after: 26,
116 utc_sec: -284040000,
117 tai_sec: -284039975, }, LeapSecond {
120 ntp_timestamp: 2918937600,
121 leap_seconds_after: 27,
122 utc_sec: -236779200,
123 tai_sec: -236779174, }, LeapSecond {
126 ntp_timestamp: 2950473600,
127 leap_seconds_after: 28,
128 utc_sec: -205243200,
129 tai_sec: -205243173, }, LeapSecond {
132 ntp_timestamp: 2982009600,
133 leap_seconds_after: 29,
134 utc_sec: -173707200,
135 tai_sec: -173707172, }, LeapSecond {
138 ntp_timestamp: 3029443200,
139 leap_seconds_after: 30,
140 utc_sec: -126273600,
141 tai_sec: -126273571, }, LeapSecond {
144 ntp_timestamp: 3076704000,
145 leap_seconds_after: 31,
146 utc_sec: -79012800,
147 tai_sec: -79012770, }, LeapSecond {
150 ntp_timestamp: 3124137600,
151 leap_seconds_after: 32,
152 utc_sec: -31579200,
153 tai_sec: -31579169, }, LeapSecond {
156 ntp_timestamp: 3345062400,
157 leap_seconds_after: 33,
158 utc_sec: 189345600,
159 tai_sec: 189345632, }, LeapSecond {
162 ntp_timestamp: 3439756800,
163 leap_seconds_after: 34,
164 utc_sec: 284040000,
165 tai_sec: 284040033, }, LeapSecond {
168 ntp_timestamp: 3550089600,
169 leap_seconds_after: 35,
170 utc_sec: 394372800,
171 tai_sec: 394372834, }, LeapSecond {
174 ntp_timestamp: 3644697600,
175 leap_seconds_after: 36,
176 utc_sec: 488980800,
177 tai_sec: 488980835, }, LeapSecond {
180 ntp_timestamp: 3692217600,
181 leap_seconds_after: 37,
182 utc_sec: 536500800,
183 tai_sec: 536500836, }, ];
186
187#[derive(Copy, Clone, Debug)]
188pub struct LeapInfo {
189 pub offset: i64,
190 pub leaps_inserted: i64,
191 pub is_leap_second: bool,
192}
193
194pub const fn get_leap_seconds(tp: &Dt, from_civil: bool) -> LeapInfo {
195 let mut offset = 0i64;
196 let mut leaps_inserted = 0i64;
197 let mut i = 0usize;
198
199 while i < LEAP_SECS.len() {
200 let entry = &LEAP_SECS[i];
201
202 let entry_sec = if from_civil {
203 entry.utc_sec
204 } else {
205 entry.tai_sec
206 };
207
208 if tp.sec() == entry_sec {
209 return LeapInfo {
210 offset: entry.leap_seconds_after,
211 leaps_inserted: i as i64 + 1,
212 is_leap_second: true,
213 };
214 }
215
216 if tp.sec() < entry_sec {
217 break;
218 }
219
220 offset = entry.leap_seconds_after;
221 leaps_inserted = i as i64 + 1;
222 i += 1;
223 }
224
225 LeapInfo {
226 offset,
227 leaps_inserted,
228 is_leap_second: false,
229 }
230}