/rust/registry/src/index.crates.io-1949cf8c6b5b557f/hifitime-4.2.3/src/epoch/initializers.rs
Line | Count | Source |
1 | | /* |
2 | | * Hifitime |
3 | | * Copyright (C) 2017-onward Christopher Rabotin <christopher.rabotin@gmail.com> et al. (cf. https://github.com/nyx-space/hifitime/graphs/contributors) |
4 | | * This Source Code Form is subject to the terms of the Mozilla Public |
5 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
6 | | * file, You can obtain one at https://mozilla.org/MPL/2.0/. |
7 | | * |
8 | | * Documentation: https://nyxspace.com/ |
9 | | */ |
10 | | |
11 | | use core::str::FromStr; |
12 | | |
13 | | use snafu::ResultExt; |
14 | | |
15 | | use crate::{ |
16 | | efmt::Format, errors::ParseSnafu, Duration, Epoch, HifitimeError, TimeScale, Unit, Weekday, |
17 | | ET_OFFSET_US, MJD_J1900, MJD_OFFSET, NANOSECONDS_PER_DAY, UNIX_REF_EPOCH, |
18 | | }; |
19 | | |
20 | | // Defines the methods that should be classmethods in Python, but must be redefined as per https://github.com/PyO3/pyo3/issues/1003#issuecomment-844433346 |
21 | | impl Epoch { |
22 | | #[must_use] |
23 | | /// Creates a new Epoch from a Duration as the time difference between this epoch and TAI reference epoch. |
24 | 24 | pub const fn from_tai_duration(duration: Duration) -> Self { |
25 | 24 | Self { |
26 | 24 | duration, |
27 | 24 | time_scale: TimeScale::TAI, |
28 | 24 | } |
29 | 24 | } |
30 | | |
31 | 0 | pub fn to_duration_since_j1900(&self) -> Duration { |
32 | 0 | self.to_time_scale(TimeScale::TAI).duration |
33 | 0 | } |
34 | | |
35 | | #[must_use] |
36 | | /// Creates a new Epoch from its centuries and nanosecond since the TAI reference epoch. |
37 | 0 | pub fn from_tai_parts(centuries: i16, nanoseconds: u64) -> Self { |
38 | 0 | Self::from_tai_duration(Duration::from_parts(centuries, nanoseconds)) |
39 | 0 | } |
40 | | |
41 | | #[must_use] |
42 | | /// Initialize an Epoch from the provided TAI seconds since 1900 January 01 at midnight |
43 | 24 | pub fn from_tai_seconds(seconds: f64) -> Self { |
44 | 24 | assert!( |
45 | 24 | seconds.is_finite(), |
46 | 0 | "Attempted to initialize Epoch with non finite number" |
47 | | ); |
48 | 24 | Self::from_tai_duration(seconds * Unit::Second) |
49 | 24 | } |
50 | | |
51 | | #[must_use] |
52 | | /// Initialize an Epoch from the provided TAI days since 1900 January 01 at midnight |
53 | 0 | pub fn from_tai_days(days: f64) -> Self { |
54 | 0 | assert!( |
55 | 0 | days.is_finite(), |
56 | 0 | "Attempted to initialize Epoch with non finite number" |
57 | | ); |
58 | 0 | Self::from_tai_duration(days * Unit::Day) |
59 | 0 | } |
60 | | |
61 | | #[must_use] |
62 | | /// Initialize an Epoch from the provided UTC seconds since 1900 January 01 at midnight |
63 | 13.7k | pub fn from_utc_duration(duration: Duration) -> Self { |
64 | 13.7k | Self::from_duration(duration, TimeScale::UTC) |
65 | 13.7k | } |
66 | | |
67 | | #[must_use] |
68 | | /// Initialize an Epoch from the provided UTC seconds since 1900 January 01 at midnight |
69 | 1.79k | pub fn from_utc_seconds(seconds: f64) -> Self { |
70 | 1.79k | Self::from_utc_duration(seconds * Unit::Second) |
71 | 1.79k | } |
72 | | |
73 | | #[must_use] |
74 | | /// Initialize an Epoch from the provided UTC days since 1900 January 01 at midnight |
75 | 0 | pub fn from_utc_days(days: f64) -> Self { |
76 | 0 | Self::from_utc_duration(days * Unit::Day) |
77 | 0 | } |
78 | | |
79 | | #[must_use] |
80 | | /// Initialize an Epoch from the provided duration since 1980 January 6 at midnight |
81 | 0 | pub fn from_gpst_duration(duration: Duration) -> Self { |
82 | 0 | Self::from_duration(duration, TimeScale::GPST) |
83 | 0 | } |
84 | | |
85 | | #[must_use] |
86 | | /// Initialize an Epoch from the provided duration since 1980 January 6 at midnight |
87 | 0 | pub fn from_qzsst_duration(duration: Duration) -> Self { |
88 | 0 | Self::from_duration(duration, TimeScale::QZSST) |
89 | 0 | } |
90 | | |
91 | | #[must_use] |
92 | | /// Initialize an Epoch from the provided duration since August 21st 1999 midnight |
93 | 0 | pub fn from_gst_duration(duration: Duration) -> Self { |
94 | 0 | Self::from_duration(duration, TimeScale::GST) |
95 | 0 | } |
96 | | |
97 | | #[must_use] |
98 | | /// Initialize an Epoch from the provided duration since January 1st midnight |
99 | 0 | pub fn from_bdt_duration(duration: Duration) -> Self { |
100 | 0 | Self::from_duration(duration, TimeScale::BDT) |
101 | 0 | } |
102 | | |
103 | | #[must_use] |
104 | 3 | pub fn from_mjd_tai(days: f64) -> Self { |
105 | 3 | Self::from_mjd_in_time_scale(days, TimeScale::TAI) |
106 | 3 | } |
107 | | |
108 | 65 | pub fn from_mjd_in_time_scale(days: f64, time_scale: TimeScale) -> Self { |
109 | 65 | assert!( |
110 | 65 | days.is_finite(), |
111 | 0 | "Attempted to initialize Epoch with non finite number" |
112 | | ); |
113 | 65 | Self { |
114 | 65 | duration: (days - MJD_J1900) * Unit::Day, |
115 | 65 | time_scale, |
116 | 65 | } |
117 | 65 | } |
118 | | |
119 | | #[must_use] |
120 | 0 | pub fn from_mjd_utc(days: f64) -> Self { |
121 | 0 | Self::from_mjd_in_time_scale(days, TimeScale::UTC) |
122 | 0 | } |
123 | | #[must_use] |
124 | 0 | pub fn from_mjd_gpst(days: f64) -> Self { |
125 | 0 | Self::from_mjd_in_time_scale(days, TimeScale::GPST) |
126 | 0 | } |
127 | | #[must_use] |
128 | 0 | pub fn from_mjd_qzsst(days: f64) -> Self { |
129 | 0 | Self::from_mjd_in_time_scale(days, TimeScale::QZSST) |
130 | 0 | } |
131 | | #[must_use] |
132 | 0 | pub fn from_mjd_gst(days: f64) -> Self { |
133 | 0 | Self::from_mjd_in_time_scale(days, TimeScale::GST) |
134 | 0 | } |
135 | | #[must_use] |
136 | 0 | pub fn from_mjd_bdt(days: f64) -> Self { |
137 | 0 | Self::from_mjd_in_time_scale(days, TimeScale::BDT) |
138 | 0 | } |
139 | | |
140 | | #[must_use] |
141 | 0 | pub fn from_jde_tai(days: f64) -> Self { |
142 | 0 | Self::from_jde_in_time_scale(days, TimeScale::TAI) |
143 | 0 | } |
144 | | |
145 | 0 | pub fn from_jde_in_time_scale(days: f64, time_scale: TimeScale) -> Self { |
146 | 0 | assert!( |
147 | 0 | days.is_finite(), |
148 | 0 | "Attempted to initialize Epoch with non finite number" |
149 | | ); |
150 | 0 | Self { |
151 | 0 | duration: (days - MJD_J1900 - MJD_OFFSET) * Unit::Day, |
152 | 0 | time_scale, |
153 | 0 | } |
154 | 0 | } |
155 | | |
156 | | #[must_use] |
157 | 0 | pub fn from_jde_utc(days: f64) -> Self { |
158 | 0 | Self::from_jde_in_time_scale(days, TimeScale::UTC) |
159 | 0 | } |
160 | | #[must_use] |
161 | 0 | pub fn from_jde_gpst(days: f64) -> Self { |
162 | 0 | Self::from_jde_in_time_scale(days, TimeScale::GPST) |
163 | 0 | } |
164 | | #[must_use] |
165 | 0 | pub fn from_jde_qzsst(days: f64) -> Self { |
166 | 0 | Self::from_jde_in_time_scale(days, TimeScale::QZSST) |
167 | 0 | } |
168 | | #[must_use] |
169 | 0 | pub fn from_jde_gst(days: f64) -> Self { |
170 | 0 | Self::from_jde_in_time_scale(days, TimeScale::GST) |
171 | 0 | } |
172 | | #[must_use] |
173 | 0 | pub fn from_jde_bdt(days: f64) -> Self { |
174 | 0 | Self::from_jde_in_time_scale(days, TimeScale::BDT) |
175 | 0 | } |
176 | | |
177 | | #[must_use] |
178 | | /// Initialize an Epoch from the provided TT seconds (approximated to 32.184s delta from TAI) |
179 | 18 | pub fn from_tt_seconds(seconds: f64) -> Self { |
180 | 18 | assert!( |
181 | 18 | seconds.is_finite(), |
182 | 0 | "Attempted to initialize Epoch with non finite number" |
183 | | ); |
184 | 18 | Self::from_tt_duration(seconds * Unit::Second) |
185 | 18 | } |
186 | | |
187 | | #[must_use] |
188 | | /// Initialize an Epoch from the provided TT seconds (approximated to 32.184s delta from TAI) |
189 | 18 | pub fn from_tt_duration(duration: Duration) -> Self { |
190 | 18 | Self::from_duration(duration, TimeScale::TT) |
191 | 18 | } |
192 | | |
193 | | #[must_use] |
194 | | /// Initialize an Epoch from the Ephemeris Time seconds past 2000 JAN 01 (J2000 reference) |
195 | 4 | pub fn from_et_seconds(seconds_since_j2000: f64) -> Epoch { |
196 | 4 | Self::from_et_duration(seconds_since_j2000 * Unit::Second) |
197 | 4 | } |
198 | | |
199 | | /// Initializes an Epoch from the duration between J2000 and the current epoch as per NAIF SPICE. |
200 | | /// |
201 | | /// # Limitation |
202 | | /// This method uses a Newton Raphson iteration to find the appropriate TAI duration. This method is only accuracy to a few nanoseconds. |
203 | | /// Hence, when calling `as_et_duration()` and re-initializing it with `from_et_duration` you may have a few nanoseconds of difference (expect less than 10 ns). |
204 | | /// |
205 | | /// # Warning |
206 | | /// The et2utc function of NAIF SPICE will assume that there are 9 leap seconds before 01 JAN 1972, |
207 | | /// as this date introduces 10 leap seconds. At the time of writing, this does _not_ seem to be in |
208 | | /// line with IERS and the documentation in the leap seconds list. |
209 | | /// |
210 | | /// In order to match SPICE, the as_et_duration() function will manually get rid of that difference. |
211 | | #[must_use] |
212 | 4 | pub fn from_et_duration(duration_since_j2000: Duration) -> Self { |
213 | 4 | Self::from_duration(duration_since_j2000, TimeScale::ET) |
214 | 4 | } |
215 | | |
216 | | #[must_use] |
217 | | /// Initialize an Epoch from Dynamic Barycentric Time (TDB) seconds past 2000 JAN 01 midnight (difference than SPICE) |
218 | | /// NOTE: This uses the ESA algorithm, which is a notch more complicated than the SPICE algorithm, but more precise. |
219 | | /// In fact, SPICE algorithm is precise +/- 30 microseconds for a century whereas ESA algorithm should be exactly correct. |
220 | 68 | pub fn from_tdb_seconds(seconds_j2000: f64) -> Epoch { |
221 | 68 | assert!( |
222 | 68 | seconds_j2000.is_finite(), |
223 | 0 | "Attempted to initialize Epoch with non finite number" |
224 | | ); |
225 | 68 | Self::from_tdb_duration(seconds_j2000 * Unit::Second) |
226 | 68 | } |
227 | | |
228 | | #[must_use] |
229 | | /// Initialize from Dynamic Barycentric Time (TDB) (same as SPICE ephemeris time) whose epoch is 2000 JAN 01 noon TAI. |
230 | 68 | pub fn from_tdb_duration(duration_since_j2000: Duration) -> Epoch { |
231 | 68 | Self::from_duration(duration_since_j2000, TimeScale::TDB) |
232 | 68 | } |
233 | | |
234 | | #[must_use] |
235 | | /// Initialize from the JDE days |
236 | 0 | pub fn from_jde_et(days: f64) -> Self { |
237 | 0 | assert!( |
238 | 0 | days.is_finite(), |
239 | 0 | "Attempted to initialize Epoch with non finite number" |
240 | | ); |
241 | 0 | Self::from_jde_tdb(days) |
242 | 0 | } |
243 | | |
244 | | #[must_use] |
245 | | /// Initialize from Dynamic Barycentric Time (TDB) (same as SPICE ephemeris time) in JD days |
246 | 0 | pub fn from_jde_tdb(days: f64) -> Self { |
247 | 0 | assert!( |
248 | 0 | days.is_finite(), |
249 | 0 | "Attempted to initialize Epoch with non finite number" |
250 | | ); |
251 | 0 | Self::from_jde_tai(days) - Unit::Microsecond * ET_OFFSET_US |
252 | 0 | } |
253 | | |
254 | | #[must_use] |
255 | | /// Initialize an Epoch from the number of seconds since the GPS Time Epoch, |
256 | | /// defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>). |
257 | 0 | pub fn from_gpst_seconds(seconds: f64) -> Self { |
258 | 0 | Self::from_duration(seconds * Unit::Second, TimeScale::GPST) |
259 | 0 | } |
260 | | |
261 | | #[must_use] |
262 | | /// Initialize an Epoch from the number of days since the GPS Time Epoch, |
263 | | /// defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>). |
264 | 0 | pub fn from_gpst_days(days: f64) -> Self { |
265 | 0 | Self::from_duration(days * Unit::Day, TimeScale::GPST) |
266 | 0 | } |
267 | | |
268 | | #[must_use] |
269 | | /// Initialize an Epoch from the number of nanoseconds since the GPS Time Epoch, |
270 | | /// defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>). |
271 | | /// This may be useful for time keeping devices that use GPS as a time source. |
272 | 0 | pub fn from_gpst_nanoseconds(nanoseconds: u64) -> Self { |
273 | 0 | Self::from_duration(Duration::from_parts(0, nanoseconds), TimeScale::GPST) |
274 | 0 | } |
275 | | |
276 | | #[must_use] |
277 | | /// Initialize an Epoch from the number of seconds since the QZSS Time Epoch, |
278 | | /// defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>). |
279 | 0 | pub fn from_qzsst_seconds(seconds: f64) -> Self { |
280 | 0 | Self::from_duration(seconds * Unit::Second, TimeScale::QZSST) |
281 | 0 | } |
282 | | |
283 | | #[must_use] |
284 | | /// Initialize an Epoch from the number of days since the QZSS Time Epoch, |
285 | | /// defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>). |
286 | 0 | pub fn from_qzsst_days(days: f64) -> Self { |
287 | 0 | Self::from_duration(days * Unit::Day, TimeScale::QZSST) |
288 | 0 | } |
289 | | |
290 | | #[must_use] |
291 | | /// Initialize an Epoch from the number of nanoseconds since the QZSS Time Epoch, |
292 | | /// defined as UTC midnight of January 5th to 6th 1980 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS#GPS_Time_.28GPST.29>). |
293 | | /// This may be useful for time keeping devices that use QZSS as a time source. |
294 | 0 | pub fn from_qzsst_nanoseconds(nanoseconds: u64) -> Self { |
295 | 0 | Self::from_duration(Duration::from_parts(0, nanoseconds), TimeScale::QZSST) |
296 | 0 | } |
297 | | |
298 | | #[must_use] |
299 | | /// Initialize an Epoch from the number of seconds since the GST Time Epoch, |
300 | | /// starting August 21st 1999 midnight (UTC) |
301 | | /// (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS>). |
302 | 0 | pub fn from_gst_seconds(seconds: f64) -> Self { |
303 | 0 | Self::from_duration(seconds * Unit::Second, TimeScale::GST) |
304 | 0 | } |
305 | | |
306 | | #[must_use] |
307 | | /// Initialize an Epoch from the number of days since the GST Time Epoch, |
308 | | /// starting August 21st 1999 midnight (UTC) |
309 | | /// (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS>) |
310 | 0 | pub fn from_gst_days(days: f64) -> Self { |
311 | 0 | Self::from_duration(days * Unit::Day, TimeScale::GST) |
312 | 0 | } |
313 | | |
314 | | #[must_use] |
315 | | /// Initialize an Epoch from the number of nanoseconds since the GPS Time Epoch, |
316 | | /// starting August 21st 1999 midnight (UTC) |
317 | | /// (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS>) |
318 | 0 | pub fn from_gst_nanoseconds(nanoseconds: u64) -> Self { |
319 | 0 | Self::from_duration(Duration::from_parts(0, nanoseconds), TimeScale::GST) |
320 | 0 | } |
321 | | |
322 | | #[must_use] |
323 | | /// Initialize an Epoch from the number of seconds since the BDT Time Epoch, |
324 | | /// starting on January 1st 2006 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS>) |
325 | 0 | pub fn from_bdt_seconds(seconds: f64) -> Self { |
326 | 0 | Self::from_duration(seconds * Unit::Second, TimeScale::BDT) |
327 | 0 | } |
328 | | |
329 | | #[must_use] |
330 | | /// Initialize an Epoch from the number of days since the BDT Time Epoch, |
331 | | /// starting on January 1st 2006 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS>) |
332 | 0 | pub fn from_bdt_days(days: f64) -> Self { |
333 | 0 | Self::from_duration(days * Unit::Day, TimeScale::BDT) |
334 | 0 | } |
335 | | |
336 | | #[must_use] |
337 | | /// Initialize an Epoch from the number of nanoseconds since the BDT Time Epoch, |
338 | | /// starting on January 1st 2006 (cf. <https://gssc.esa.int/navipedia/index.php/Time_References_in_GNSS>). |
339 | | /// This may be useful for time keeping devices that use BDT as a time source. |
340 | 0 | pub fn from_bdt_nanoseconds(nanoseconds: u64) -> Self { |
341 | 0 | Self::from_duration(Duration::from_parts(0, nanoseconds), TimeScale::BDT) |
342 | 0 | } |
343 | | |
344 | | #[must_use] |
345 | | /// Initialize an Epoch from the provided IEEE 1588-2008 (PTPv2) duration since TAI midnight 1970 January 01. |
346 | | /// PTP uses the TAI timescale but with the Unix Epoch for compatibility with unix systems. |
347 | 0 | pub fn from_ptp_duration(duration: Duration) -> Self { |
348 | 0 | Self::from_duration(UNIX_REF_EPOCH.to_utc_duration() + duration, TimeScale::TAI) |
349 | 0 | } |
350 | | |
351 | | #[must_use] |
352 | | /// Initialize an Epoch from the provided IEEE 1588-2008 (PTPv2) second timestamp since TAI midnight 1970 January 01. |
353 | | /// PTP uses the TAI timescale but with the Unix Epoch for compatibility with unix systems. |
354 | 0 | pub fn from_ptp_seconds(seconds: f64) -> Self { |
355 | 0 | Self::from_ptp_duration(seconds * Unit::Second) |
356 | 0 | } |
357 | | |
358 | | #[must_use] |
359 | | /// Initialize an Epoch from the provided IEEE 1588-2008 (PTPv2) nanoseconds timestamp since TAI midnight 1970 January 01. |
360 | | /// PTP uses the TAI timescale but with the Unix Epoch for compatibility with unix systems. |
361 | 0 | pub fn from_ptp_nanoseconds(nanoseconds: u64) -> Self { |
362 | 0 | Self::from_ptp_duration(Duration::from_parts(0, nanoseconds)) |
363 | 0 | } |
364 | | |
365 | | #[must_use] |
366 | | /// Initialize an Epoch from the provided duration since UTC midnight 1970 January 01. |
367 | 11.9k | pub fn from_unix_duration(duration: Duration) -> Self { |
368 | 11.9k | Self::from_utc_duration(UNIX_REF_EPOCH.to_utc_duration() + duration) |
369 | 11.9k | } |
370 | | |
371 | | #[must_use] |
372 | | /// Initialize an Epoch from the provided UNIX second timestamp since UTC midnight 1970 January 01. |
373 | 0 | pub fn from_unix_seconds(seconds: f64) -> Self { |
374 | 0 | Self::from_utc_duration(UNIX_REF_EPOCH.to_utc_duration() + seconds * Unit::Second) |
375 | 0 | } |
376 | | |
377 | | #[must_use] |
378 | | /// Initialize an Epoch from the provided UNIX millisecond timestamp since UTC midnight 1970 January 01. |
379 | 0 | pub fn from_unix_milliseconds(millisecond: f64) -> Self { |
380 | 0 | Self::from_utc_duration(UNIX_REF_EPOCH.to_utc_duration() + millisecond * Unit::Millisecond) |
381 | 0 | } |
382 | | |
383 | | /// Initializes an Epoch from the provided Format. |
384 | 0 | pub fn from_str_with_format(s_in: &str, format: Format) -> Result<Self, HifitimeError> { |
385 | 0 | format.parse(s_in) |
386 | 0 | } |
387 | | |
388 | | /// Initializes an Epoch from the Format as a string. |
389 | 0 | pub fn from_format_str(s_in: &str, format_str: &str) -> Result<Self, HifitimeError> { |
390 | 0 | Format::from_str(format_str) |
391 | 0 | .with_context(|_| ParseSnafu { |
392 | | details: "when using format string", |
393 | 0 | })? |
394 | 0 | .parse(s_in) |
395 | 0 | } |
396 | | |
397 | | /// Builds an Epoch from given `week`: elapsed weeks counter into the desired Time scale, and the amount of nanoseconds within that week. |
398 | | /// For example, this is how GPS vehicles describe a GPST epoch. |
399 | | /// |
400 | | /// Note that this constructor relies on 128 bit integer math and may be slow on embedded devices. |
401 | | #[must_use] |
402 | 0 | pub fn from_time_of_week(week: u32, nanoseconds: u64, time_scale: TimeScale) -> Self { |
403 | 0 | let mut nanos = i128::from(nanoseconds); |
404 | 0 | nanos += i128::from(week) * Weekday::DAYS_PER_WEEK_I128 * i128::from(NANOSECONDS_PER_DAY); |
405 | 0 | let duration = Duration::from_total_nanoseconds(nanos); |
406 | 0 | Self::from_duration(duration, time_scale) |
407 | 0 | } |
408 | | |
409 | | #[must_use] |
410 | | /// Builds a UTC Epoch from given `week`: elapsed weeks counter and "ns" amount of nanoseconds since closest Sunday Midnight. |
411 | 0 | pub fn from_time_of_week_utc(week: u32, nanoseconds: u64) -> Self { |
412 | 0 | Self::from_time_of_week(week, nanoseconds, TimeScale::UTC) |
413 | 0 | } |
414 | | |
415 | | #[must_use] |
416 | | /// Builds an Epoch from the provided year, days in the year, and a time scale. |
417 | | /// |
418 | | /// # Limitations |
419 | | /// In the TDB or ET time scales, there may be an error of up to 750 nanoseconds when initializing an Epoch this way. |
420 | | /// This is because we first initialize the epoch in Gregorian scale and then apply the TDB/ET offset, but that offset actually depends on the precise time. |
421 | | /// |
422 | | /// # Day couting behavior |
423 | | /// |
424 | | /// The day counter starts at 01, in other words, 01 January is day 1 of the counter, as per the GPS specificiations. |
425 | | /// |
426 | 0 | pub fn from_day_of_year(year: i32, days: f64, time_scale: TimeScale) -> Self { |
427 | 0 | let start_of_year = Self::from_gregorian(year, 1, 1, 0, 0, 0, 0, time_scale); |
428 | 0 | start_of_year + (days - 1.0) * Unit::Day |
429 | 0 | } |
430 | | } |