1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use crate::{Dt, Real, Scale};
impl Dt {
/// Returns the **Julian epoch year**.
#[inline]
pub const fn to_jyear(&self) -> Real {
let jd_tt = self.to_jd_f();
f!(2000.0) + (jd_tt - f!(2451545.0)) / f!(365.25)
}
/// Inverse of [`Self::to_jyear`].
#[inline]
pub const fn from_jyear(jyear: Real, scale: Scale) -> Self {
if jyear.is_nan() {
return Self::ZERO;
}
if jyear.is_infinite() {
return if jyear.is_sign_positive() {
Self::MAX
} else {
Self::MIN
};
}
let jd = f!(2451545.0) + (jyear - f!(2000.0)) * f!(365.25);
Self::from_jd_f(jd, scale)
}
/// Returns the **Besselian epoch year**.
#[inline]
pub const fn to_byear(&self) -> Real {
let jd_tt = self.to_jd_f();
f!(1900.0) + (jd_tt - f!(2415020.31352)) / f!(365.242198781)
}
/// Inverse of [`Self::to_byear`].
#[inline]
pub const fn from_byear(byear: Real, scale: Scale) -> Self {
if byear.is_nan() {
return Self::ZERO;
}
if byear.is_infinite() {
return if byear.is_sign_positive() {
Self::MAX
} else {
Self::MIN
};
}
let jd = f!(2415020.31352) + (byear - f!(1900.0)) * f!(365.242198781);
Self::from_jd_f(jd, scale)
}
/// Returns the **decimal year** (Gregorian calendar year + fraction of the year).
///
/// This is the direct equivalent of Astropy’s `Time.decimalyear`:
/// - Uses the *actual* length of the specific Gregorian year (365 or 366 days,
/// plus any leap seconds on UTC/UTCSpice/etc.).
/// - Fully scale-aware (TAI, TT, UTC, TDB, custom clocks, …).
/// - Exact integer arithmetic for the year boundaries, then a high-precision
/// `to_sec_f` division (lossy only at the final `Real` step, same as Astropy).
#[inline]
pub const fn to_decimalyear(&self, current: Scale) -> Real {
let ymd = self.to_ymdhms(current);
let year = ymd.yr;
let start = Self::from_ymd_on(year, 1, 1, current);
let next_start = Self::from_ymd_on(year + 1, 1, 1, current);
let elapsed = self.to_diff_raw(start).to_sec_f();
let year_length = next_start.to_diff_raw(start).to_sec_f();
// year_length is never zero for representable years
f!(year) + elapsed / year_length
}
}