/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sofars-0.6.1/src/ts/taiutc.rs
Line | Count | Source |
1 | | use super::utctai; |
2 | | |
3 | | /// Time scale transformation: International Atomic Time, TAI, to |
4 | | /// Coordinated Universal Time, UTC. |
5 | | /// |
6 | | /// This function is part of the International Astronomical Union's |
7 | | /// SOFA (Standards of Fundamental Astronomy) software collection. |
8 | | /// |
9 | | /// Status: canonical. |
10 | | /// |
11 | | /// Given: |
12 | | /// tai1,tai2 double TAI as a 2-part Julian Date (Note 1) |
13 | | /// |
14 | | /// Returned: |
15 | | /// utc1,utc2 double UTC as a 2-part quasi Julian Date (Notes 1-3) |
16 | | /// |
17 | | /// Returned (function value): |
18 | | /// int status: +1 = dubious year (Note 4) |
19 | | /// 0 = OK |
20 | | /// -1 = unacceptable date |
21 | | /// |
22 | | /// Notes: |
23 | | /// |
24 | | /// 1) tai1+tai2 is Julian Date, apportioned in any convenient way |
25 | | /// between the two arguments, for example where tai1 is the Julian |
26 | | /// Day Number and tai2 is the fraction of a day. The returned utc1 |
27 | | /// and utc2 form an analogous pair, except that a special convention |
28 | | /// is used, to deal with the problem of leap seconds - see the next |
29 | | /// note. |
30 | | /// |
31 | | /// 2) JD cannot unambiguously represent UTC during a leap second unless |
32 | | /// special measures are taken. The convention in the present |
33 | | /// function is that the JD day represents UTC days whether the |
34 | | /// length is 86399, 86400 or 86401 SI seconds. In the 1960-1972 era |
35 | | /// there were smaller jumps (in either direction) each time the |
36 | | /// linear UTC(TAI) expression was changed, and these "mini-leaps" |
37 | | /// are also included in the SOFA convention. |
38 | | /// |
39 | | /// 3) The function iauD2dtf can be used to transform the UTC quasi-JD |
40 | | /// into calendar date and clock time, including UTC leap second |
41 | | /// handling. |
42 | | /// |
43 | | /// 4) The warning status "dubious year" flags UTCs that predate the |
44 | | /// introduction of the time scale or that are too far in the future |
45 | | /// to be trusted. See iauDat for further details. |
46 | | /// |
47 | | /// Called: |
48 | | /// iauUtctai UTC to TAI |
49 | | /// |
50 | 0 | pub fn taiutc(tai1: f64, tai2: f64) -> Result<(f64, f64), i32> { |
51 | | let (a1, a2); |
52 | | let u1; |
53 | | let mut u2; |
54 | | let (mut g1, mut g2); |
55 | | |
56 | | /* Put the two parts of the TAI into big-first order. */ |
57 | 0 | let big1 = tai1.abs() >= tai2.abs(); |
58 | 0 | if big1 { |
59 | 0 | a1 = tai1; |
60 | 0 | a2 = tai2; |
61 | 0 | } else { |
62 | 0 | a1 = tai2; |
63 | 0 | a2 = tai1; |
64 | 0 | } |
65 | | |
66 | | /* Initial guess for UTC. */ |
67 | 0 | u1 = a1; |
68 | 0 | u2 = a2; |
69 | | |
70 | | /* Iterate (though in most cases just once is enough). */ |
71 | 0 | for _ in 0..3 { |
72 | | /* Guessed UTC to TAI. */ |
73 | 0 | match utctai(u1, u2) { |
74 | 0 | Ok((r1, r2)) => { |
75 | 0 | g1 = r1; |
76 | 0 | g2 = r2; |
77 | 0 | } |
78 | 0 | Err(status) => { |
79 | 0 | return Err(status); |
80 | | } |
81 | | } |
82 | | |
83 | | /* Adjust guessed UTC. */ |
84 | 0 | u2 += a1 - g1; |
85 | 0 | u2 += a2 - g2; |
86 | | } |
87 | | |
88 | | /* Return the UTC result, preserving the TAI order. */ |
89 | 0 | if big1 { |
90 | 0 | Ok((u1, u2)) |
91 | | } else { |
92 | 0 | Ok((u2, u1)) |
93 | | } |
94 | 0 | } |