/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sofars-0.6.2/src/cal/jd2cal.rs
Line | Count | Source |
1 | 0 | pub fn jd2cal(dj1: f64, dj2: f64) -> Result<(i32, i32, i32, f64), i32> { |
2 | | /* Minimum and maximum allowed JD */ |
3 | | const DJMIN: f64 = -68569.5; |
4 | | const DJMAX: f64 = 1e9; |
5 | | |
6 | | let mut jd: i64; |
7 | | let mut l: i64; |
8 | | |
9 | | let mut d: f64; |
10 | | let mut s: f64; |
11 | | let mut cs: f64; |
12 | | |
13 | | let mut x: f64; |
14 | | let mut t: f64; |
15 | | let mut f: f64; |
16 | | |
17 | | /* Verify date is acceptable. */ |
18 | 0 | let dj: f64 = dj1 + dj2; |
19 | 0 | if dj < DJMIN || dj > DJMAX { |
20 | 0 | return Err(-1); |
21 | 0 | } |
22 | | |
23 | | /* Separate day and fraction (where -0.5 <= fraction < 0.5). */ |
24 | 0 | d = dj1.round(); |
25 | 0 | let f1: f64 = dj1 - d; |
26 | 0 | jd = d as i64; |
27 | 0 | d = dj2.round(); |
28 | 0 | let f2: f64 = dj2 - d; |
29 | 0 | jd += d as i64; |
30 | | |
31 | | /* Compute f1+f2+0.5 using compensated summation (Klein 2006). */ |
32 | 0 | s = 0.5; |
33 | 0 | cs = 0.0; |
34 | 0 | let v: [f64; 2] = [f1, f2]; |
35 | 0 | for i in 0..2 { |
36 | 0 | x = v[i]; |
37 | 0 | t = s + x; |
38 | 0 | cs += if s.abs() >= x.abs() { |
39 | 0 | (s - t) + x |
40 | | } else { |
41 | 0 | (x - t) + s |
42 | | }; |
43 | 0 | s = t; |
44 | 0 | if s >= 1.0 { |
45 | 0 | jd += 1; |
46 | 0 | s -= 1.0; |
47 | 0 | } |
48 | | } |
49 | 0 | f = s + cs; |
50 | 0 | cs = f - s; |
51 | | |
52 | | /* Deal with negative f. */ |
53 | 0 | if f < 0.0 { |
54 | 0 | /* Compensated summation: assume that |s| <= 1.0. */ |
55 | 0 | f = s + 1.0; |
56 | 0 | cs += (1.0 - f) + s; |
57 | 0 | s = f; |
58 | 0 | f = s + cs; |
59 | 0 | cs = f - s; |
60 | 0 | jd -= 1; |
61 | 0 | } |
62 | | |
63 | | /* Deal with f that is 1.0 or more (when rounded to double). */ |
64 | 0 | if (f - 1.0) >= -f64::EPSILON / 4.0 { |
65 | | /* Compensated summation: assume that |s| <= 1.0. */ |
66 | 0 | t = s - 1.0; |
67 | 0 | cs += (s - t) - 1.0; |
68 | 0 | s = t; |
69 | 0 | f = s + cs; |
70 | 0 | if -f64::EPSILON / 2.0 < f { |
71 | 0 | jd += 1; |
72 | 0 | f = f.max(0.0); |
73 | 0 | } |
74 | 0 | } |
75 | | |
76 | | /* Express day in Gregorian calendar. */ |
77 | 0 | l = jd + 68569; |
78 | 0 | let n: i64 = (4 * l) / 146097; |
79 | 0 | l -= (146097 * n + 3) / 4; |
80 | 0 | let i = (4000 * (l + 1)) / 1461001; |
81 | 0 | l -= (1461 * i) / 4 - 31; |
82 | 0 | let k: i64 = (80 * l) / 2447; |
83 | 0 | let id = (l - (2447 * k) / 80) as i32; |
84 | 0 | l = k / 11; |
85 | 0 | let im = (k + 2 - 12 * l) as i32; |
86 | 0 | let iy = (100 * (n - 49) + i + l) as i32; |
87 | 0 | let fd = f; |
88 | | |
89 | | /* Success. */ |
90 | 0 | Ok((iy, im, id, fd)) |
91 | 0 | } |