/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sofars-0.6.1/src/cal/jdcalf.rs
Line | Count | Source |
1 | | use crate::cal::jd2cal; |
2 | | |
3 | | /// Julian Date to Gregorian Calendar, expressed in a form convenient |
4 | | /// for formatting messages: rounded to a specified precision. |
5 | | /// |
6 | | /// This function is part of the International Astronomical Union's |
7 | | /// SOFA (Standards of Fundamental Astronomy) software collection. |
8 | | /// |
9 | | /// Status: support function. |
10 | | /// |
11 | | /// # Given: |
12 | | /// * `ndp`: number of decimal places of days in fraction |
13 | | /// * `dj1`, `dj2`: dj1+dj2 = Julian Date (Note 1) |
14 | | /// |
15 | | /// # Returned: |
16 | | /// * `(iy, im, id, iymdf_3)`: year, month, day, fraction in Gregorian calendar |
17 | | /// |
18 | | /// # Returned (function value): |
19 | | /// * `Result`: |
20 | | /// * `Ok(status)`: |
21 | | /// * `0` = OK |
22 | | /// * `1` = ndp not 0-9 (interpreted as 0) |
23 | | /// * `Err(status)`: |
24 | | /// * `-1` = date out of range |
25 | | /// |
26 | | /// # Notes: |
27 | | /// 1) The Julian Date is apportioned in any convenient way between |
28 | | /// the arguments dj1 and dj2. For example, JD=2450123.7 could |
29 | | /// be expressed in any of these ways, among others: |
30 | | /// |
31 | | /// dj1 dj2 |
32 | | /// |
33 | | /// 2450123.7 0.0 (JD method) |
34 | | /// 2451545.0 -1421.3 (J2000 method) |
35 | | /// 2400000.5 50123.2 (MJD method) |
36 | | /// 2450123.5 0.2 (date & time method) |
37 | | /// |
38 | | /// 2) In early eras the conversion is from the "Proleptic Gregorian |
39 | | /// Calendar"; no account is taken of the date(s) of adoption of |
40 | | /// the Gregorian Calendar, nor is the AD/BC numbering convention |
41 | | /// observed. |
42 | | /// |
43 | | /// 3) See also the function iauJd2cal. |
44 | | /// |
45 | | /// 4) The number of decimal places ndp should be 4 or less if internal |
46 | | /// overflows are to be avoided on platforms which use 16-bit |
47 | | /// integers. |
48 | | /// |
49 | | /// # Reference: |
50 | | /// Explanatory Supplement to the Astronomical Almanac, |
51 | | /// P. Kenneth Seidelmann (ed), University Science Books (1992), |
52 | | /// Section 12.92 (p604). |
53 | 0 | pub fn jdcalf(ndp: i32, dj1: f64, dj2: f64) -> Result<(i32, i32, i32, i32, i32), i32> { |
54 | | let j; |
55 | | let denom; |
56 | | |
57 | | /* Denominator of fraction (e.g. 100 for 2 decimal places). */ |
58 | 0 | if (ndp >= 0) && (ndp <= 9) { |
59 | 0 | j = 0; |
60 | 0 | denom = 10.0f64.powi(ndp); |
61 | 0 | } else { |
62 | 0 | j = 1; |
63 | 0 | denom = 1.0; |
64 | 0 | } |
65 | | |
66 | | /* Copy the date, big then small. */ |
67 | 0 | let (mut d1, d2) = if dj1.abs() >= dj2.abs() { |
68 | 0 | (dj1, dj2) |
69 | | } else { |
70 | 0 | (dj2, dj1) |
71 | | }; |
72 | | |
73 | | /* Realign to midnight (without rounding error). */ |
74 | 0 | d1 -= 0.5; |
75 | | |
76 | | /* Separate day and fraction (as precisely as possible). */ |
77 | 0 | let mut d = dnint(d1); |
78 | 0 | let f1 = d1 - d; |
79 | 0 | let mut djd = d; |
80 | 0 | d = dnint(d2); |
81 | 0 | let f2 = d2 - d; |
82 | 0 | djd += d; |
83 | 0 | d = dnint(f1 + f2); |
84 | 0 | let mut f = (f1 - d) + f2; |
85 | 0 | if f < 0.0 { |
86 | 0 | f += 1.0; |
87 | 0 | d -= 1.0; |
88 | 0 | } |
89 | 0 | djd += d; |
90 | | |
91 | | /* Round the total fraction to the specified number of places. */ |
92 | 0 | let rf = dnint(f * denom) / denom; |
93 | | |
94 | | /* Re-align to noon. */ |
95 | 0 | djd += 0.5; |
96 | | |
97 | | /* Convert to Gregorian calendar. */ |
98 | 0 | match jd2cal(djd, rf) { |
99 | 0 | Ok((iy, im, id, f_out)) => { |
100 | 0 | let iymdf_3 = dnint(f_out * denom) as i32; |
101 | 0 | Ok((iy, im, id, iymdf_3, j)) |
102 | | } |
103 | 0 | Err(js) => Err(js), |
104 | | } |
105 | 0 | } |
106 | | |
107 | | /* dnint(A) - round to nearest whole number (double) */ |
108 | 0 | fn dnint(a: f64) -> f64 { |
109 | 0 | if a.abs() < 0.5 { |
110 | 0 | 0.0 |
111 | 0 | } else if a < 0.0 { |
112 | 0 | (a - 0.5).ceil() |
113 | | } else { |
114 | 0 | (a + 0.5).floor() |
115 | | } |
116 | 0 | } |