docs: bilingual comments for time, leap, coord and geodesy
Four of the five physics crates are done, 104 of 239 blocks in the layer. The remaining one is apsis-frames, which holds the IAU 2000 Earth orientation models and carries the largest number of formulas.
This commit is contained in:
parent
f76bf654df
commit
64114251fa
|
|
@ -12,6 +12,11 @@ use apsis_math::Vec3;
|
|||
/// The frame is aligned with the mean equator and equinox of J2000.0 and is
|
||||
/// treated as inertial, so it does not rotate with the Earth. Coordinates
|
||||
/// are in meters.
|
||||
///
|
||||
/// 地心惯性系中的笛卡尔位置。
|
||||
///
|
||||
/// 该系与 J2000.0 的平赤道平春分点对齐,并视为惯性系,故不随地球自转。
|
||||
/// 坐标单位为米。
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Eci(Vec3);
|
||||
|
||||
|
|
@ -19,6 +24,10 @@ pub struct Eci(Vec3);
|
|||
///
|
||||
/// The frame rotates with the Earth, so a point fixed to the ground has
|
||||
/// constant coordinates in it. Coordinates are in meters.
|
||||
///
|
||||
/// 地心地固系中的笛卡尔位置。
|
||||
///
|
||||
/// 该系随地球自转,故地面上固定的点在其中坐标恒定。坐标单位为米。
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Ecef(Vec3);
|
||||
|
||||
|
|
@ -28,22 +37,32 @@ pub struct Ecef(Vec3);
|
|||
/// Latitude and longitude are in radians and height is in meters. Latitude
|
||||
/// is geodetic, measured between the ellipsoid normal and the equatorial
|
||||
/// plane.
|
||||
///
|
||||
/// 以纬度、经度与 WGS 84 椭球高给出的地固系位置。
|
||||
///
|
||||
/// 纬度与经度用弧度,高用米。纬度为大地纬度,在椭球法线与赤道面之间量取。
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Geodetic(EllipsoidalPosition);
|
||||
|
||||
impl Eci {
|
||||
/// Creates an inertial position from a vector in meters.
|
||||
///
|
||||
/// 由米为单位的向量创建惯性位置。
|
||||
pub const fn new(vector: Vec3) -> Self {
|
||||
Self(vector)
|
||||
}
|
||||
|
||||
/// Returns the position in meters.
|
||||
///
|
||||
/// 返回以米为单位的位置。
|
||||
pub const fn vector(self) -> Vec3 {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Converts this inertial position to the Earth-fixed frame at the given
|
||||
/// Earth Rotation Angle.
|
||||
///
|
||||
/// 按给定的地球自转角把该惯性位置转换到地固系。
|
||||
pub fn to_ecef(self, angle: EarthRotationAngle) -> Ecef {
|
||||
Ecef(rotation_eci_to_ecef(angle) * self.0)
|
||||
}
|
||||
|
|
@ -51,17 +70,23 @@ impl Eci {
|
|||
|
||||
impl Ecef {
|
||||
/// Creates an Earth-fixed position from a vector in meters.
|
||||
///
|
||||
/// 由米为单位的向量创建地固位置。
|
||||
pub const fn new(vector: Vec3) -> Self {
|
||||
Self(vector)
|
||||
}
|
||||
|
||||
/// Returns the position in meters.
|
||||
///
|
||||
/// 返回以米为单位的位置。
|
||||
pub const fn vector(self) -> Vec3 {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Converts this Earth-fixed position to the inertial frame at the given
|
||||
/// Earth Rotation Angle.
|
||||
///
|
||||
/// 按给定的地球自转角把该地固位置转换到惯性系。
|
||||
pub fn to_eci(self, angle: EarthRotationAngle) -> Eci {
|
||||
Eci(rotation_ecef_to_eci(angle) * self.0)
|
||||
}
|
||||
|
|
@ -71,6 +96,10 @@ impl Ecef {
|
|||
///
|
||||
/// Returns `None` when the position lies on the polar axis, where no
|
||||
/// longitude is defined.
|
||||
///
|
||||
/// 把该地固位置转换为给定椭球之上的纬度、经度与高。
|
||||
///
|
||||
/// 当位置落在极轴上时返回 `None`,因为那里经度未定义。
|
||||
pub fn to_geodetic(self, ellipsoid: Ellipsoid) -> Option<Geodetic> {
|
||||
geodetic_from_cartesian(self.0, ellipsoid).map(Geodetic)
|
||||
}
|
||||
|
|
@ -80,26 +109,38 @@ impl Geodetic {
|
|||
/// Creates a geodetic position from latitude, longitude, and height.
|
||||
///
|
||||
/// Latitude and longitude are in radians and height is in meters.
|
||||
///
|
||||
/// 由纬度、经度与高创建大地位置。
|
||||
///
|
||||
/// 纬度与经度用弧度,高用米。
|
||||
pub const fn new(latitude: f64, longitude: f64, height: f64) -> Self {
|
||||
Self(EllipsoidalPosition::new(latitude, longitude, height))
|
||||
}
|
||||
|
||||
/// Returns the geodetic latitude in radians.
|
||||
///
|
||||
/// 返回大地纬度,单位为弧度。
|
||||
pub const fn latitude(self) -> f64 {
|
||||
self.0.latitude
|
||||
}
|
||||
|
||||
/// Returns the longitude in radians, positive east.
|
||||
///
|
||||
/// 返回经度,单位为弧度,向东为正。
|
||||
pub const fn longitude(self) -> f64 {
|
||||
self.0.longitude
|
||||
}
|
||||
|
||||
/// Returns the height above the ellipsoid in meters.
|
||||
///
|
||||
/// 返回椭球高,单位为米。
|
||||
pub const fn height(self) -> f64 {
|
||||
self.0.height
|
||||
}
|
||||
|
||||
/// Returns the underlying ellipsoidal position.
|
||||
///
|
||||
/// 返回底层的椭球位置。
|
||||
pub const fn ellipsoidal(self) -> EllipsoidalPosition {
|
||||
self.0
|
||||
}
|
||||
|
|
@ -109,12 +150,18 @@ impl Geodetic {
|
|||
///
|
||||
/// This is the common case. Use [`Geodetic::to_ecef_on`] for a different
|
||||
/// ellipsoid.
|
||||
///
|
||||
/// 把该位置转换到 WGS 84 椭球的地固系。
|
||||
///
|
||||
/// 这是常见情形。需用其他椭球时请用 [`Geodetic::to_ecef_on`]。
|
||||
pub fn to_ecef(self) -> Ecef {
|
||||
self.to_ecef_on(WGS84)
|
||||
}
|
||||
|
||||
/// Converts this position to the Earth-fixed frame on the given
|
||||
/// ellipsoid.
|
||||
///
|
||||
/// 把该位置转换到给定椭球的地固系。
|
||||
pub fn to_ecef_on(self, ellipsoid: Ellipsoid) -> Ecef {
|
||||
Ecef(cartesian_from_geodetic(self.0, ellipsoid))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,13 @@
|
|||
/// there is no risk of the parameters disagreeing with each other.
|
||||
///
|
||||
/// Lengths are in meters and angles are in radians.
|
||||
///
|
||||
/// 双轴参考椭球:绕短轴旋转所得的椭圆。
|
||||
///
|
||||
/// 形状由两个数确定。本 crate 存储半长轴与逆扁率,它们是标准中 WGS 84 椭球的
|
||||
/// 两个定义参数。其余量都由二者导出,故各参数之间不会失配。
|
||||
///
|
||||
/// 长度单位为米,角度单位为弧度。
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Ellipsoid {
|
||||
semi_major_axis: f64,
|
||||
|
|
@ -21,6 +28,10 @@ impl Ellipsoid {
|
|||
///
|
||||
/// Lengths are in meters. The inverse flattening must be positive and
|
||||
/// finite; a value of infinity describes a sphere.
|
||||
///
|
||||
/// 由半长轴与逆扁率创建椭球。
|
||||
///
|
||||
/// 长度单位为米。逆扁率必须为正且有限;取无穷大则描述一个球。
|
||||
pub const fn new(semi_major_axis: f64, inverse_flattening: f64) -> Self {
|
||||
Self {
|
||||
semi_major_axis,
|
||||
|
|
@ -29,11 +40,15 @@ impl Ellipsoid {
|
|||
}
|
||||
|
||||
/// Returns the semi-major axis, in meters.
|
||||
///
|
||||
/// 返回半长轴,单位为米。
|
||||
pub const fn semi_major_axis(self) -> f64 {
|
||||
self.semi_major_axis
|
||||
}
|
||||
|
||||
/// Returns the inverse flattening.
|
||||
///
|
||||
/// 返回逆扁率。
|
||||
pub const fn inverse_flattening(self) -> f64 {
|
||||
self.inverse_flattening
|
||||
}
|
||||
|
|
@ -41,11 +56,17 @@ impl Ellipsoid {
|
|||
/// Returns the flattening.
|
||||
///
|
||||
/// This is zero for a sphere.
|
||||
///
|
||||
/// 返回扁率。
|
||||
///
|
||||
/// 对球其值为零。
|
||||
pub fn flattening(self) -> f64 {
|
||||
1.0 / self.inverse_flattening
|
||||
}
|
||||
|
||||
/// Returns the semi-minor axis, in meters.
|
||||
///
|
||||
/// 返回半短轴,单位为米。
|
||||
pub fn semi_minor_axis(self) -> f64 {
|
||||
self.semi_major_axis * (1.0 - self.flattening())
|
||||
}
|
||||
|
|
@ -54,12 +75,18 @@ impl Ellipsoid {
|
|||
/// `[0, 1)`.
|
||||
///
|
||||
/// It is `2f - f^2` for flattening `f`.
|
||||
///
|
||||
/// 返回第一偏心率平方,为位于 `[0, 1)` 的无量纲数。
|
||||
///
|
||||
/// 对扁率 `f`,它等于 `2f - f^2`。
|
||||
pub fn eccentricity_squared(self) -> f64 {
|
||||
let flattening = self.flattening();
|
||||
2.0 * flattening - flattening * flattening
|
||||
}
|
||||
|
||||
/// Returns the first eccentricity, a dimensionless number in `[0, 1)`.
|
||||
///
|
||||
/// 返回第一偏心率,为位于 `[0, 1)` 的无量纲数。
|
||||
pub fn eccentricity(self) -> f64 {
|
||||
self.eccentricity_squared().sqrt()
|
||||
}
|
||||
|
|
@ -68,6 +95,10 @@ impl Ellipsoid {
|
|||
///
|
||||
/// It is `e^2 / (1 - e^2)`, which appears in the closed form for
|
||||
/// converting a geodetic position to Cartesian coordinates.
|
||||
///
|
||||
/// 返回第二偏心率平方,为无量纲数。
|
||||
///
|
||||
/// 它等于 `e^2 / (1 - e^2)`,出现在把大地位置转换为笛卡尔坐标的闭式解中。
|
||||
pub fn second_eccentricity_squared(self) -> f64 {
|
||||
let squared = self.eccentricity_squared();
|
||||
squared / (1.0 - squared)
|
||||
|
|
@ -77,6 +108,10 @@ impl Ellipsoid {
|
|||
///
|
||||
/// This is the radius of curvature in the meridian at the pole, equal
|
||||
/// to `a / sqrt(1 - e^2)`.
|
||||
///
|
||||
/// 返回极半径曲率,单位为米。
|
||||
///
|
||||
/// 它是极点处子午线上的曲率半径,等于 `a / sqrt(1 - e^2)`。
|
||||
pub fn polar_radius_of_curvature(self) -> f64 {
|
||||
self.semi_major_axis / (1.0 - self.eccentricity_squared()).sqrt()
|
||||
}
|
||||
|
|
@ -89,6 +124,13 @@ impl Ellipsoid {
|
|||
/// the equator to [`Ellipsoid::polar_radius_of_curvature`] at the pole.
|
||||
///
|
||||
/// The latitude is in radians.
|
||||
///
|
||||
/// 返回给定大地纬度处卯酉圈上的曲率半径,单位为米。
|
||||
///
|
||||
/// 它是沿椭球法线从表面量到极轴的距离,由赤道处的半长轴增长到极点的
|
||||
/// [`Ellipsoid::polar_radius_of_curvature`]。
|
||||
///
|
||||
/// 纬度单位为弧度。
|
||||
pub fn prime_vertical_radius(self, latitude: f64) -> f64 {
|
||||
let sin = latitude.sin();
|
||||
self.semi_major_axis / (1.0 - self.eccentricity_squared() * sin * sin).sqrt()
|
||||
|
|
@ -98,6 +140,10 @@ impl Ellipsoid {
|
|||
/// geodetic latitude, in meters.
|
||||
///
|
||||
/// The latitude is in radians.
|
||||
///
|
||||
/// 返回给定大地纬度处子午线上的曲率半径,单位为米。
|
||||
///
|
||||
/// 纬度单位为弧度。
|
||||
pub fn meridian_radius(self, latitude: f64) -> f64 {
|
||||
let sin = latitude.sin();
|
||||
let squared = self.eccentricity_squared();
|
||||
|
|
@ -112,6 +158,11 @@ impl Ellipsoid {
|
|||
/// radius vector, while the geodetic latitude is measured to the
|
||||
/// ellipsoid normal. The geocentric value is the smaller of the two
|
||||
/// away from the equator and the poles.
|
||||
///
|
||||
/// 返回与给定大地纬度对应的地心纬度,单位为弧度。
|
||||
///
|
||||
/// 地心纬度自赤道面量到径向矢量,而大地纬度量到椭球法线。除赤道与极点外,
|
||||
/// 地心纬度小于大地纬度。
|
||||
pub fn geocentric_latitude(self, geodetic_latitude: f64) -> f64 {
|
||||
let squared = self.eccentricity_squared();
|
||||
let tangent = (1.0 - squared) * geodetic_latitude.tan();
|
||||
|
|
@ -125,6 +176,12 @@ impl Ellipsoid {
|
|||
/// the inverse flattening `1 / f = 298.257 223 563`.
|
||||
///
|
||||
/// Source: NIMA TR8350.2, third edition, 2000.
|
||||
///
|
||||
/// WGS 84 参考椭球。
|
||||
///
|
||||
/// 两个定义参数为半长轴 `a = 6 378 137 m` 与逆扁率 `1 / f = 298.257 223 563`。
|
||||
///
|
||||
/// 出处:NIMA TR8350.2 第三版,2000。
|
||||
pub const WGS84: Ellipsoid = Ellipsoid::new(6_378_137.0, 298.257_223_563);
|
||||
|
||||
/// The Earth gravitational parameter for WGS 84, in cubic meters per second
|
||||
|
|
@ -133,4 +190,9 @@ pub const WGS84: Ellipsoid = Ellipsoid::new(6_378_137.0, 298.257_223_563);
|
|||
/// This is held here rather than in `apsis-core` so that a caller working
|
||||
/// with the ellipsoid can use the matching gravity field. The value is
|
||||
/// `3.986 004 418e14 m^3/s^2`.
|
||||
///
|
||||
/// WGS 84 的地球引力参数,单位为立方米每二次方秒。
|
||||
///
|
||||
/// 该值置于此处而非 `apsis-core`,以便处理椭球的调用方使用与之匹配的重力场。
|
||||
/// 其值为 `3.986 004 418e14 m^3/s^2`。
|
||||
pub const WGS84_GRAVITATIONAL_PARAMETER: f64 = 3.986_004_418e14;
|
||||
|
|
|
|||
|
|
@ -17,18 +17,32 @@ use apsis_math::Vec3;
|
|||
/// plane, and lies in `[-pi/2, pi/2]`. Longitude is measured east from the
|
||||
/// prime meridian. Height is the distance along the ellipsoid normal, taken
|
||||
/// as positive outside the ellipsoid.
|
||||
///
|
||||
/// 大地位置:纬度、经度与椭球高。
|
||||
///
|
||||
/// 纬度与经度用弧度,高用米。纬度为大地纬度,在椭球法线与赤道面之间量取,位于
|
||||
/// `[-pi/2, pi/2]`。经度自本初子午线向东量取。高是沿椭球法线的距离,椭球
|
||||
/// 之外取正。
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Geodetic {
|
||||
/// Geodetic latitude, in radians.
|
||||
///
|
||||
/// 大地纬度,单位为弧度。
|
||||
pub latitude: f64,
|
||||
/// Longitude, in radians, positive east.
|
||||
///
|
||||
/// 经度,单位为弧度,向东为正。
|
||||
pub longitude: f64,
|
||||
/// Height above the ellipsoid, in meters.
|
||||
///
|
||||
/// 椭球高,单位为米。
|
||||
pub height: f64,
|
||||
}
|
||||
|
||||
impl Geodetic {
|
||||
/// Creates a geodetic position from latitude, longitude, and height.
|
||||
///
|
||||
/// 由纬度、经度与高创建大地位置。
|
||||
pub const fn new(latitude: f64, longitude: f64, height: f64) -> Self {
|
||||
Self {
|
||||
latitude,
|
||||
|
|
@ -57,12 +71,30 @@ impl Geodetic {
|
|||
/// where `N` is the prime vertical radius of curvature. This form is
|
||||
/// exact everywhere, including at the poles, where the cosine factors
|
||||
/// vanish.
|
||||
///
|
||||
/// 把该大地位置转换为给定椭球上的地固笛卡尔坐标。
|
||||
///
|
||||
/// 该系的第三轴沿椭球短轴指向北极,第一轴过赤道与本初子午线之交,第二轴构成
|
||||
/// 右手系。结果单位为米。
|
||||
///
|
||||
/// 闭式解为
|
||||
///
|
||||
/// ```text
|
||||
/// N = a / sqrt(1 - e^2 sin^2(lat))
|
||||
/// x = (N + h) cos(lat) cos(lon)
|
||||
/// y = (N + h) cos(lat) sin(lon)
|
||||
/// z = (N (1 - e^2) + h) sin(lat)
|
||||
/// ```
|
||||
///
|
||||
/// 其中 `N` 为卯酉圈曲率半径。该形式处处精确,包括余弦因子为零的极点。
|
||||
pub fn to_cartesian(self, ellipsoid: Ellipsoid) -> Vec3 {
|
||||
cartesian_from_geodetic(self, ellipsoid)
|
||||
}
|
||||
|
||||
/// Returns `true` when every field is finite and the latitude and
|
||||
/// longitude are inside their ranges.
|
||||
///
|
||||
/// 当各字段都有限,且纬度与经度位于其范围内时返回 `true`。
|
||||
pub fn is_valid(self) -> bool {
|
||||
let half_pi = core::f64::consts::FRAC_PI_2;
|
||||
self.latitude.is_finite()
|
||||
|
|
@ -79,6 +111,10 @@ impl Geodetic {
|
|||
///
|
||||
/// See [`Geodetic::to_cartesian`] for the frame definition and the closed
|
||||
/// form.
|
||||
///
|
||||
/// 把大地位置转换为地固笛卡尔坐标。
|
||||
///
|
||||
/// 坐标系定义与闭式解见 [`Geodetic::to_cartesian`]。
|
||||
pub fn cartesian_from_geodetic(geodetic: Geodetic, ellipsoid: Ellipsoid) -> Vec3 {
|
||||
let Geodetic {
|
||||
latitude,
|
||||
|
|
@ -107,6 +143,13 @@ pub fn cartesian_from_geodetic(geodetic: Geodetic, ellipsoid: Ellipsoid) -> Vec3
|
|||
///
|
||||
/// Returns `None` when the position is not finite, or when it lies on the
|
||||
/// polar axis so that no longitude is defined.
|
||||
///
|
||||
/// 把地固笛卡尔坐标转换为大地位置。
|
||||
///
|
||||
/// 纬度与高由 Bowring 方法求得:先以闭式解解出子午线方程,再用若干不动点迭代
|
||||
/// 精化。对从椭球下方到地球同步半径范围内的位置,该迭代收敛到远优于一微米。
|
||||
///
|
||||
/// 当位置非有限,或落在极轴上以致经度未定义时返回 `None`。
|
||||
pub fn geodetic_from_cartesian(cartesian: Vec3, ellipsoid: Ellipsoid) -> Option<Geodetic> {
|
||||
let Vec3 { x, y, z } = cartesian;
|
||||
if !cartesian.is_finite() {
|
||||
|
|
@ -121,6 +164,7 @@ pub fn geodetic_from_cartesian(cartesian: Vec3, ellipsoid: Ellipsoid) -> Option<
|
|||
let horizontal_squared = x * x + y * y;
|
||||
if horizontal_squared == 0.0 {
|
||||
// On the polar axis the longitude is undefined.
|
||||
// 在极轴上经度未定义。
|
||||
return None;
|
||||
}
|
||||
let horizontal = horizontal_squared.sqrt();
|
||||
|
|
@ -128,6 +172,7 @@ pub fn geodetic_from_cartesian(cartesian: Vec3, ellipsoid: Ellipsoid) -> Option<
|
|||
|
||||
// Bowring's initial latitude estimate, obtained by treating the point
|
||||
// as if it lay on a locally spherical surface.
|
||||
// Bowring 的纬度初值估计,做法是把该点视为位于局部球面上。
|
||||
let theta = (z * semi_major).atan2(horizontal * semi_minor);
|
||||
let (sin_theta, cos_theta) = theta.sin_cos();
|
||||
let mut latitude = (z + second_squared * semi_minor * sin_theta * sin_theta * sin_theta)
|
||||
|
|
@ -136,6 +181,8 @@ pub fn geodetic_from_cartesian(cartesian: Vec3, ellipsoid: Ellipsoid) -> Option<
|
|||
// Refine with fixed point steps on the ellipsoid equation. Three steps
|
||||
// reduce the error to the floating point noise floor for every
|
||||
// terrestrial altitude.
|
||||
// 用椭球方程的不动点迭代精化。三步即可把误差降到浮点噪声水平,适用于
|
||||
// 任何地面高度。
|
||||
for _ in 0..3 {
|
||||
let (sin_latitude, _) = latitude.sin_cos();
|
||||
latitude = (z + squared * ellipsoid.prime_vertical_radius(latitude) * sin_latitude)
|
||||
|
|
@ -145,6 +192,7 @@ pub fn geodetic_from_cartesian(cartesian: Vec3, ellipsoid: Ellipsoid) -> Option<
|
|||
let (sin_latitude, cos_latitude) = latitude.sin_cos();
|
||||
// Guard against a latitude that has converged exactly to a pole, where
|
||||
// the division below would be singular.
|
||||
// 防止纬度恰好收敛到极点,否则下文的除法为奇异。
|
||||
if cos_latitude == 0.0 {
|
||||
return None;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,15 +7,28 @@
|
|||
/// effect. It does not record the size of the inserted second, because in
|
||||
/// every announcement to date the inserted second was exactly one second
|
||||
/// and the new offset is one greater than the previous one.
|
||||
///
|
||||
/// 一条闰秒公告。
|
||||
///
|
||||
/// 该条目记录 `TAI - UTC` 新值生效的日期。它不记录所插入闰秒的长度,因为迄今
|
||||
/// 每一次公告插入的闰秒都恰为一秒,且新偏移比前一个大一。
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct LeapSecond {
|
||||
/// Year of the effective date, in the proleptic Gregorian calendar.
|
||||
///
|
||||
/// 生效日期的年,前推格里历。
|
||||
pub year: i32,
|
||||
/// Month of the effective date, in `1..=12`.
|
||||
///
|
||||
/// 生效日期的月,取值 `1..=12`。
|
||||
pub month: u32,
|
||||
/// Day of the effective date, in `1..=31`.
|
||||
///
|
||||
/// 生效日期的日,取值 `1..=31`。
|
||||
pub day: u32,
|
||||
/// The value of `TAI - UTC` in seconds from this date onward.
|
||||
///
|
||||
/// 自该日起生效的 `TAI - UTC` 值,单位为秒。
|
||||
pub tai_minus_utc: f64,
|
||||
}
|
||||
|
||||
|
|
@ -24,6 +37,10 @@ impl LeapSecond {
|
|||
///
|
||||
/// Leap seconds take effect at 00:00:00 UTC, so the effective instant
|
||||
/// is the start of the given calendar day.
|
||||
///
|
||||
/// 返回生效瞬时的修正儒略日(Modified Julian Date)。
|
||||
///
|
||||
/// 闰秒在 00:00:00 UTC 生效,故生效瞬时即该日历日的起点。
|
||||
pub const fn effective_mjd(self) -> f64 {
|
||||
mjd_from_ymd(self.year, self.month, self.day)
|
||||
}
|
||||
|
|
@ -34,6 +51,11 @@ impl LeapSecond {
|
|||
/// Source: IERS Bulletin C. The first entry is 1972-01-01, when the
|
||||
/// current scheme began with an initial offset of 10 s inherited from
|
||||
/// earlier adjustments.
|
||||
///
|
||||
/// 闰秒表,按生效日期排序。
|
||||
///
|
||||
/// 出处:IERS Bulletin C。首条为 1972-01-01,即现行方案开始之时,其初始偏移
|
||||
/// 10 s 承自更早的调整。
|
||||
pub const LEAP_SECONDS: &[LeapSecond] = &[
|
||||
LeapSecond {
|
||||
year: 1972,
|
||||
|
|
@ -209,6 +231,10 @@ pub const LEAP_SECONDS: &[LeapSecond] = &[
|
|||
///
|
||||
/// Queries earlier than this instant are rejected because UTC did not yet
|
||||
/// use integer second offsets.
|
||||
///
|
||||
/// 表中首条的修正儒略日(Modified Julian Date),1972-01-01。
|
||||
///
|
||||
/// 早于该瞬时的查询会被拒绝,因为那时的 UTC 尚未采用整数秒偏移。
|
||||
pub const TABLE_COVERS_FROM_MJD: f64 = mjd_from_ymd(
|
||||
LEAP_SECONDS[0].year,
|
||||
LEAP_SECONDS[0].month,
|
||||
|
|
@ -219,6 +245,10 @@ pub const TABLE_COVERS_FROM_MJD: f64 = mjd_from_ymd(
|
|||
///
|
||||
/// This is the offset that remains in force until a new leap second is
|
||||
/// announced.
|
||||
///
|
||||
/// 自表中末条起生效的 `TAI - UTC` 值。
|
||||
///
|
||||
/// 在新的闰秒公布之前,该偏移持续有效。
|
||||
pub const TAI_MINUS_UTC_AFTER_LAST_ENTRY: f64 = LEAP_SECONDS[LEAP_SECONDS.len() - 1].tai_minus_utc;
|
||||
|
||||
/// Converts a proleptic Gregorian calendar date to a Modified Julian Date.
|
||||
|
|
@ -230,6 +260,14 @@ pub const TAI_MINUS_UTC_AFTER_LAST_ENTRY: f64 = LEAP_SECONDS[LEAP_SECONDS.len()
|
|||
/// The computation is done in `i64` and converted once at the end, so the
|
||||
/// result is exact for the range of dates in which a leap second can
|
||||
/// plausibly occur.
|
||||
///
|
||||
/// 把前推格里历日期转换为修正儒略日(Modified Julian Date)。
|
||||
///
|
||||
/// 结果是给定日期 00:00:00 的 MJD。算法采用 Fliegel-Van Flandern 整数换算,
|
||||
/// 对格里历定义范围内的每个日期都精确,且无需查表。
|
||||
///
|
||||
/// 计算在 `i64` 中进行并仅在末尾换算一次,故在闰秒可能发生的日期范围内结果
|
||||
/// 精确。
|
||||
pub const fn mjd_from_ymd(year: i32, month: u32, day: u32) -> f64 {
|
||||
let a = (14 - month as i64) / 12;
|
||||
let y = year as i64 + 4800 - a;
|
||||
|
|
@ -237,5 +275,7 @@ pub const fn mjd_from_ymd(year: i32, month: u32, day: u32) -> f64 {
|
|||
let jdn = day as i64 + (153 * m + 2) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 32045;
|
||||
// The Julian Day Number counts days from noon, and MJD 0 is the
|
||||
// midnight starting 1858-11-17, whose Julian Day Number is 2 400 001.
|
||||
// 儒略日数从正午起计,而 MJD 0 是始于 1858-11-17 的午夜,其儒略日数为
|
||||
// 2 400 001。
|
||||
(jdn - 2_400_001) as f64
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,16 @@ use crate::table::{
|
|||
///
|
||||
/// MJD carries no time scale of its own, so this constant is the same
|
||||
/// number whether the instant is read in UTC, TAI, or any other scale.
|
||||
///
|
||||
/// Unix 历元的修正儒略日(Modified Julian Date),1970-01-01T00:00:00。
|
||||
///
|
||||
/// MJD 本身不携带时间标度,故无论该瞬时按 UTC、TAI 还是其他标度读取,此常量
|
||||
/// 都是同一个数。
|
||||
pub const MJD_AT_UNIX_EPOCH: f64 = 40_587.0;
|
||||
|
||||
/// The number of seconds in a day.
|
||||
///
|
||||
/// 一天中的秒数。
|
||||
const SECONDS_PER_DAY: f64 = 86_400.0;
|
||||
|
||||
/// Returns the value of `TAI - UTC` in seconds at the given UTC Modified
|
||||
|
|
@ -23,6 +30,14 @@ const SECONDS_PER_DAY: f64 = 86_400.0;
|
|||
///
|
||||
/// Returns `None` when the instant precedes 1972-01-01, before which UTC
|
||||
/// used fractional offsets and this table does not apply.
|
||||
///
|
||||
/// 返回给定 UTC 修正儒略日(Modified Julian Date)处 `TAI - UTC` 的秒值。
|
||||
///
|
||||
/// 该偏移是阶跃函数:它在每个闰秒生效日的 00:00:00 UTC 改变,其间保持不变。
|
||||
/// 恰在生效日上的查询返回新值。
|
||||
///
|
||||
/// 当该瞬时早于 1972-01-01 时返回 `None`,因为那之前 UTC 采用小数偏移,本表
|
||||
/// 不适用。
|
||||
pub fn tai_minus_utc_at_mjd(utc_mjd: f64) -> Option<f64> {
|
||||
if !utc_mjd.is_finite() || utc_mjd < TABLE_COVERS_FROM_MJD {
|
||||
return None;
|
||||
|
|
@ -47,6 +62,14 @@ pub fn tai_minus_utc_at_mjd(utc_mjd: f64) -> Option<f64> {
|
|||
/// leap second makes some TAI instants correspond to no UTC instant.
|
||||
///
|
||||
/// Returns `None` when the instant precedes 1972-01-01.
|
||||
///
|
||||
/// 把 UTC 修正儒略日(Modified Julian Date)转换为对应的 TAI 修正儒略日。
|
||||
///
|
||||
/// 换算加上该瞬时生效的偏移。由于偏移是在 UTC 侧求值的阶跃函数,正向换算对每个
|
||||
/// UTC 瞬时都有定义;反向换算则不然,因为闰秒使某些 TAI 瞬时不对应任何 UTC
|
||||
/// 瞬时。
|
||||
///
|
||||
/// 当该瞬时早于 1972-01-01 时返回 `None`。
|
||||
pub fn tai_mjd_from_utc_mjd(utc_mjd: f64) -> Option<f64> {
|
||||
let offset = tai_minus_utc_at_mjd(utc_mjd)?;
|
||||
Some(utc_mjd + offset / SECONDS_PER_DAY)
|
||||
|
|
@ -66,6 +89,15 @@ pub fn tai_mjd_from_utc_mjd(utc_mjd: f64) -> Option<f64> {
|
|||
/// inserted leap second. Such an instant has no UTC representation, because
|
||||
/// the UTC clock labels that interval `23:59:60`, a value that does not
|
||||
/// exist on the continuous Modified Julian Date scale.
|
||||
///
|
||||
/// 把 TAI 修正儒略日(Modified Julian Date)转换为对应的 UTC 修正儒略日。
|
||||
///
|
||||
/// 表中每个候选偏移依次尝试;当所得 UTC 瞬时处生效的偏移与产生它的偏移相同时,
|
||||
/// 该候选被接受。对给定输入至多有一个偏移满足该条件,故搜索无歧义。
|
||||
///
|
||||
/// 两种情形返回 `None`。其一是早于表中起点的瞬时,那里的 UTC 采用小数偏移,本表
|
||||
/// 未予描述。其二是严格落在所插入闰秒内部的瞬时,此类瞬时没有 UTC 表示,因为
|
||||
/// UTC 时钟把该区间标记为 `23:59:60`,而该值在连续的修正儒略日标度上并不存在。
|
||||
pub fn utc_mjd_from_tai_mjd(tai_mjd: f64) -> Option<f64> {
|
||||
if !tai_mjd.is_finite() {
|
||||
return None;
|
||||
|
|
@ -87,6 +119,11 @@ pub fn utc_mjd_from_tai_mjd(tai_mjd: f64) -> Option<f64> {
|
|||
/// the leap second table entries. It is provided so that callers do not
|
||||
/// have to reproduce the conversion, and because the calibration scripts in
|
||||
/// `validation/` need the same function on both sides of a comparison.
|
||||
///
|
||||
/// 把前推格里历日期在 00:00:00 的瞬时转换为修正儒略日(Modified Julian Date)。
|
||||
///
|
||||
/// 这是用于定位闰秒表条目的日历换算之便捷再导出。提供它是为了免去调用方重复
|
||||
/// 实现该换算,也因为 `validation/` 中的标定脚本在比较的两侧都需要同一函数。
|
||||
pub const fn calendar_mjd(year: i32, month: u32, day: u32) -> f64 {
|
||||
mjd_from_ymd(year, month, day)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
use core::fmt;
|
||||
|
||||
/// The number of seconds in a day, not counting leap seconds.
|
||||
///
|
||||
/// 一天中的秒数,不计闰秒。
|
||||
pub const SECONDS_PER_DAY: f64 = 86_400.0;
|
||||
|
||||
/// A calendar date and time of day.
|
||||
|
|
@ -31,24 +33,46 @@ pub const SECONDS_PER_DAY: f64 = 86_400.0;
|
|||
/// otherwise occupy. This crate therefore treats leap seconds only where
|
||||
/// they are unambiguous, in the `TAI - UTC` offset lookup, and not as
|
||||
/// calendar instants.
|
||||
///
|
||||
/// 日历日期与日内时刻。
|
||||
///
|
||||
/// 各字段为前推格里历的字段。`second` 是位于 `[0, 60)` 的浮点数。
|
||||
///
|
||||
/// 秒数不会达到 60。闰秒在 UTC 中写作第 60 秒,但该标记在连续时间标度上并没有
|
||||
/// 唯一位置:它占据的区间正是随后午夜本应占据的区间。因此本 crate 只在无歧义的
|
||||
/// 位置处理闰秒,即 `TAI - UTC` 偏移查表中,而不把它当作日历瞬时。
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub struct Calendar {
|
||||
/// Year, negative for years before year 1.
|
||||
///
|
||||
/// 年,公元 1 年之前为负。
|
||||
pub year: i32,
|
||||
/// Month in `1..=12`.
|
||||
///
|
||||
/// 月,取值 `1..=12`。
|
||||
pub month: u32,
|
||||
/// Day of month in `1..=31`.
|
||||
///
|
||||
/// 日,取值 `1..=31`。
|
||||
pub day: u32,
|
||||
/// Hour in `0..=23`.
|
||||
///
|
||||
/// 时,取值 `0..=23`。
|
||||
pub hour: u32,
|
||||
/// Minute in `0..=59`.
|
||||
///
|
||||
/// 分,取值 `0..=59`。
|
||||
pub minute: u32,
|
||||
/// Second in `[0, 61)`.
|
||||
///
|
||||
/// 秒,取值 `[0, 61)`。
|
||||
pub second: f64,
|
||||
}
|
||||
|
||||
impl Calendar {
|
||||
/// Creates a calendar date from its fields.
|
||||
///
|
||||
/// 由各字段创建日历日期。
|
||||
pub const fn new(year: i32, month: u32, day: u32, hour: u32, minute: u32, second: f64) -> Self {
|
||||
Self {
|
||||
year,
|
||||
|
|
@ -61,17 +85,23 @@ impl Calendar {
|
|||
}
|
||||
|
||||
/// Creates a calendar date at the start of the given day.
|
||||
///
|
||||
/// 在给定日期的起点创建日历日期。
|
||||
pub const fn from_ymd(year: i32, month: u32, day: u32) -> Self {
|
||||
Self::new(year, month, day, 0, 0, 0.0)
|
||||
}
|
||||
|
||||
/// Returns the seconds elapsed since the start of the day.
|
||||
///
|
||||
/// 返回自该日起点已过去的秒数。
|
||||
pub fn seconds_of_day(self) -> f64 {
|
||||
f64::from(self.hour) * 3_600.0 + f64::from(self.minute) * 60.0 + self.second
|
||||
}
|
||||
|
||||
/// Returns `true` when the fields form a date that exists in the
|
||||
/// proleptic Gregorian calendar.
|
||||
///
|
||||
/// 当各字段构成前推格里历中存在的日期时返回 `true`。
|
||||
pub fn is_valid(self) -> bool {
|
||||
(1..=12).contains(&self.month)
|
||||
&& self.day >= 1
|
||||
|
|
@ -95,6 +125,8 @@ impl fmt::Display for Calendar {
|
|||
|
||||
/// Returns `true` when `year` is a leap year in the proleptic Gregorian
|
||||
/// calendar.
|
||||
///
|
||||
/// 当 `year` 是前推格里历中的闰年时返回 `true`。
|
||||
pub const fn is_leap_year(year: i32) -> bool {
|
||||
(year % 4 == 0 && year % 100 != 0) || year % 400 == 0
|
||||
}
|
||||
|
|
@ -102,6 +134,10 @@ pub const fn is_leap_year(year: i32) -> bool {
|
|||
/// Returns the number of days in the given month of the given year.
|
||||
///
|
||||
/// Returns zero when `month` is outside `1..=12`.
|
||||
///
|
||||
/// 返回给定年给定月的天数。
|
||||
///
|
||||
/// `month` 超出 `1..=12` 时返回零。
|
||||
pub const fn days_in_month(year: i32, month: u32) -> u32 {
|
||||
match month {
|
||||
1 | 3 | 5 | 7 | 8 | 10 | 12 => 31,
|
||||
|
|
@ -123,10 +159,17 @@ pub const fn days_in_month(year: i32, month: u32) -> u32 {
|
|||
/// The result is the MJD of the start of the given day, so it is an
|
||||
/// integer. The time of day is ignored; use [`Calendar::seconds_of_day`] to
|
||||
/// account for it.
|
||||
///
|
||||
/// 把日历日期(忽略日内时刻)转换为修正儒略日(Modified Julian Date)。
|
||||
///
|
||||
/// 结果是该日起点的 MJD,故为整数。日内时刻被忽略;若需计入,请用
|
||||
/// [`Calendar::seconds_of_day`]。
|
||||
pub const fn mjd_from_ymd(year: i32, month: u32, day: u32) -> f64 {
|
||||
// Shift the year so that March is the first month, which places the
|
||||
// leap day at the end of the shifted year and removes a special case
|
||||
// from the day count.
|
||||
// 平移年份使三月成为首月,从而把闰日置于平移后年份的末尾,免去天数统计中
|
||||
// 的特例。
|
||||
let a = (14 - month as i64) / 12;
|
||||
let y = year as i64 + 4800 - a;
|
||||
let m = month as i64 + 12 * a - 3;
|
||||
|
|
@ -138,6 +181,10 @@ pub const fn mjd_from_ymd(year: i32, month: u32, day: u32) -> f64 {
|
|||
///
|
||||
/// The fractional part is ignored, so the result is the calendar day
|
||||
/// containing the instant.
|
||||
///
|
||||
/// 把修正儒略日(Modified Julian Date)转换为日历日期。
|
||||
///
|
||||
/// 小数部分被忽略,故结果是包含该瞬时的日历日。
|
||||
pub fn ymd_from_mjd(mjd: f64) -> (i32, u32, u32) {
|
||||
let jdn = mjd.floor() as i64 + 2_400_001;
|
||||
let a = jdn + 32_044;
|
||||
|
|
@ -155,6 +202,10 @@ pub fn ymd_from_mjd(mjd: f64) -> (i32, u32, u32) {
|
|||
/// Keeps only the fractional part of an MJD as seconds since midnight.
|
||||
///
|
||||
/// The result lies in `[0, 86400)` for any finite input.
|
||||
///
|
||||
/// 只保留 MJD 的小数部分,表示为自午夜起的秒数。
|
||||
///
|
||||
/// 对任何有限输入,结果都位于 `[0, 86400)`。
|
||||
pub fn seconds_of_day_from_mjd(mjd: f64) -> f64 {
|
||||
let fraction = mjd - mjd.floor();
|
||||
fraction * SECONDS_PER_DAY
|
||||
|
|
|
|||
|
|
@ -21,6 +21,10 @@ use core::fmt;
|
|||
///
|
||||
/// The field is private so that the stored scale is guaranteed. Use
|
||||
/// [`Epoch::from_mjd`] or the named constructors to build one.
|
||||
///
|
||||
/// TAI 时间尺度上的一个瞬时,以修正儒略日(Modified Julian Date)存储。
|
||||
///
|
||||
/// 字段私有以保证所存标度确定。用 [`Epoch::from_mjd`] 或具名构造函数创建。
|
||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
|
||||
pub struct Epoch {
|
||||
tai_mjd: f64,
|
||||
|
|
@ -30,14 +34,22 @@ impl Epoch {
|
|||
/// The instant 2000-01-01T12:00:00 TT, which defines the J2000.0 epoch.
|
||||
///
|
||||
/// The value is `2451545.0` on the TT scale, offset back to TAI.
|
||||
///
|
||||
/// 瞬时 2000-01-01T12:00:00 TT,定义了 J2000.0 历元。
|
||||
///
|
||||
/// 该值在 TT 标度上为 `2451545.0`,并回退到 TAI。
|
||||
pub const J2000: Self = Self::from_tai_mjd_const(51_544.5 - TT_MINUS_TAI / SECONDS_PER_DAY);
|
||||
|
||||
/// Creates an epoch from a Modified Julian Date on the TAI scale.
|
||||
///
|
||||
/// 由 TAI 标度上的修正儒略日创建历元。
|
||||
pub const fn from_tai_mjd(tai_mjd: f64) -> Self {
|
||||
Self { tai_mjd }
|
||||
}
|
||||
|
||||
/// Const constructor used by the associated constants.
|
||||
///
|
||||
/// 供各关联常量使用的 const 构造函数。
|
||||
const fn from_tai_mjd_const(tai_mjd: f64) -> Self {
|
||||
Self { tai_mjd }
|
||||
}
|
||||
|
|
@ -47,6 +59,11 @@ impl Epoch {
|
|||
/// Returns `None` when the instant cannot be expressed on the requested
|
||||
/// scale. This happens for UTC before 1972, where the leap second table
|
||||
/// used to convert from UTC does not apply.
|
||||
///
|
||||
/// 由给定标度上的修正儒略日(Modified Julian Date)创建历元。
|
||||
///
|
||||
/// 当该瞬时无法在所请求的标度上表达时返回 `None`。这发生在 1972 年之前的
|
||||
/// UTC,因为用于从 UTC 换算的闰秒表不适用。
|
||||
pub fn from_mjd(mjd: f64, scale: TimeScale) -> Option<Self> {
|
||||
if !mjd.is_finite() {
|
||||
return None;
|
||||
|
|
@ -68,6 +85,10 @@ impl Epoch {
|
|||
///
|
||||
/// Returns `None` when the fields do not form a valid date, or when the
|
||||
/// instant cannot be expressed on the requested scale.
|
||||
///
|
||||
/// 由日历日期创建历元,并按给定标度解释该日期。
|
||||
///
|
||||
/// 当各字段不构成有效日期,或该瞬时无法在所请求的标度上表达时返回 `None`。
|
||||
pub fn from_calendar(calendar: Calendar, scale: TimeScale) -> Option<Self> {
|
||||
if !calendar.is_valid() {
|
||||
return None;
|
||||
|
|
@ -78,6 +99,8 @@ impl Epoch {
|
|||
}
|
||||
|
||||
/// Returns the instant as a Modified Julian Date on the TAI scale.
|
||||
///
|
||||
/// 返回该瞬时在 TAI 标度上的修正儒略日(Modified Julian Date)。
|
||||
pub const fn tai_mjd(self) -> f64 {
|
||||
self.tai_mjd
|
||||
}
|
||||
|
|
@ -86,6 +109,11 @@ impl Epoch {
|
|||
///
|
||||
/// Returns `None` when the instant precedes 1972 and the UTC scale is
|
||||
/// requested, because the leap second table does not cover that range.
|
||||
///
|
||||
/// 返回该瞬时在给定标度上的修正儒略日(Modified Julian Date)。
|
||||
///
|
||||
/// 当该瞬时早于 1972 年且请求 UTC 标度时返回 `None`,因为闰秒表不覆盖该
|
||||
/// 区间。
|
||||
pub fn mjd(self, scale: TimeScale) -> Option<f64> {
|
||||
match scale {
|
||||
TimeScale::Tai => Some(self.tai_mjd),
|
||||
|
|
@ -99,6 +127,10 @@ impl Epoch {
|
|||
///
|
||||
/// Returns `None` when the scale conversion is not available for this
|
||||
/// instant; see [`Epoch::mjd`].
|
||||
///
|
||||
/// 返回该瞬时在给定标度上的日历日期。
|
||||
///
|
||||
/// 当该瞬时不可进行标度换算时返回 `None`;参见 [`Epoch::mjd`]。
|
||||
pub fn calendar(self, scale: TimeScale) -> Option<Calendar> {
|
||||
let mjd = self.mjd(scale)?;
|
||||
let (year, month, day) = ymd_from_mjd(mjd);
|
||||
|
|
@ -121,6 +153,11 @@ impl Epoch {
|
|||
/// The result is positive when `other` is later. Because both epochs
|
||||
/// are stored on the uniform TAI scale, the difference is exact and
|
||||
/// does not depend on the scales used to create either epoch.
|
||||
///
|
||||
/// 返回从 `self` 到 `other` 的带符号秒数。
|
||||
///
|
||||
/// 当 `other` 更晚时结果为正。由于两个历元都存于均匀的 TAI 标度,差值
|
||||
/// 精确,且与创建二者时所用的标度无关。
|
||||
pub fn seconds_until(self, other: Self) -> f64 {
|
||||
(other.tai_mjd - self.tai_mjd) * SECONDS_PER_DAY
|
||||
}
|
||||
|
|
@ -134,6 +171,13 @@ impl Epoch {
|
|||
/// does not have a single well defined numeric value across such an
|
||||
/// instant. Callers that need calendar arithmetic on the UTC scale
|
||||
/// should convert to a [`Calendar`], adjust it, and convert back.
|
||||
///
|
||||
/// 返回平移 `seconds` 后的历元。
|
||||
///
|
||||
/// 平移量以均匀 TAI 标度上的 SI 秒计,故瞬时恰好前进相同的流逝时间。这是
|
||||
/// 唯一提供的平移方式:若按 UTC 时钟平移,当区间跨越插入的闰秒时结果会
|
||||
/// 不同,而 UTC 时钟在该瞬时前后没有单一良定义的数值。需要按 UTC 标度做
|
||||
/// 日历运算的调用方,应先转为 [`Calendar`]、调整后再转回。
|
||||
pub fn add_seconds(self, seconds: f64) -> Self {
|
||||
Self {
|
||||
tai_mjd: self.tai_mjd + seconds / SECONDS_PER_DAY,
|
||||
|
|
@ -141,6 +185,8 @@ impl Epoch {
|
|||
}
|
||||
|
||||
/// Returns `true` when the stored Modified Julian Date is finite.
|
||||
///
|
||||
/// 当所存修正儒略日(Modified Julian Date)有限时返回 `true`。
|
||||
pub const fn is_finite(self) -> bool {
|
||||
self.tai_mjd.is_finite()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,14 +11,20 @@
|
|||
|
||||
/// The number of days between the start of the Julian Date scale and the
|
||||
/// start of the Modified Julian Date scale.
|
||||
///
|
||||
/// 儒略日标度起点与修正儒略日标度起点之间的天数。
|
||||
pub const JULIAN_DATE_OFFSET: f64 = 2_400_000.5;
|
||||
|
||||
/// Converts a Julian Date to a Modified Julian Date.
|
||||
///
|
||||
/// 把儒略日(Julian Date)转换为修正儒略日(Modified Julian Date)。
|
||||
pub const fn mjd_from_julian_date(julian_date: f64) -> f64 {
|
||||
julian_date - JULIAN_DATE_OFFSET
|
||||
}
|
||||
|
||||
/// Converts a Modified Julian Date to a Julian Date.
|
||||
///
|
||||
/// 把修正儒略日(Modified Julian Date)转换为儒略日(Julian Date)。
|
||||
pub const fn julian_date_from_mjd(mjd: f64) -> f64 {
|
||||
mjd + JULIAN_DATE_OFFSET
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,11 +20,19 @@ use core::fmt;
|
|||
/// Terrestrial Time minus International Atomic Time, in seconds.
|
||||
///
|
||||
/// Exact by the definition of Terrestrial Time.
|
||||
///
|
||||
/// 地球时(TT)减国际原子时(TAI),单位为秒。
|
||||
///
|
||||
/// 由地球时的定义精确确定。
|
||||
pub const TT_MINUS_TAI: f64 = 32.184;
|
||||
|
||||
/// International Atomic Time minus GPS time, in seconds.
|
||||
///
|
||||
/// Exact by the definition of GPS time.
|
||||
///
|
||||
/// 国际原子时(TAI)减 GPS 时,单位为秒。
|
||||
///
|
||||
/// 由 GPS 时的定义精确确定。
|
||||
pub const TAI_MINUS_GPS: f64 = 19.0;
|
||||
|
||||
/// A time scale.
|
||||
|
|
@ -32,15 +40,28 @@ pub const TAI_MINUS_GPS: f64 = 19.0;
|
|||
/// The scale determines how a numeric instant is interpreted. It does not
|
||||
/// change the instant itself; converting an [`Epoch`](crate::Epoch) between
|
||||
/// scales only changes the number used to display it.
|
||||
///
|
||||
/// 时间尺度。
|
||||
///
|
||||
/// 标度决定一个数值瞬时如何被解释,但并不改变瞬时本身;把
|
||||
/// [`Epoch`](crate::Epoch) 在标度之间换算,只改变用于显示它的数值。
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub enum TimeScale {
|
||||
/// Coordinated Universal Time, adjusted by leap seconds.
|
||||
///
|
||||
/// 世界协调时,由闰秒调整。
|
||||
Utc,
|
||||
/// International Atomic Time, a uniform scale.
|
||||
///
|
||||
/// 国际原子时,均匀标度。
|
||||
Tai,
|
||||
/// Terrestrial Time, a uniform scale defined for geocentric work.
|
||||
///
|
||||
/// 地球时,为地心工作定义的均匀标度。
|
||||
Tt,
|
||||
/// GPS time, a uniform scale maintained by the GPS constellation.
|
||||
///
|
||||
/// GPS 时,由 GPS 星座维持的均匀标度。
|
||||
Gps,
|
||||
}
|
||||
|
||||
|
|
@ -49,11 +70,17 @@ impl TimeScale {
|
|||
///
|
||||
/// UTC is the only scale here that is not uniform, because leap seconds
|
||||
/// make some of its minutes 61 seconds long.
|
||||
///
|
||||
/// 当该标度以均匀速率运行时返回 `true`。
|
||||
///
|
||||
/// 此处只有 UTC 不是均匀的,因为闰秒使其部分分钟长达 61 秒。
|
||||
pub const fn is_uniform(self) -> bool {
|
||||
!matches!(self, Self::Utc)
|
||||
}
|
||||
|
||||
/// Returns the short name of the scale, such as `TAI` or `UTC`.
|
||||
///
|
||||
/// 返回该标度的简称,例如 `TAI` 或 `UTC`。
|
||||
pub const fn name(self) -> &'static str {
|
||||
match self {
|
||||
Self::Utc => "UTC",
|
||||
|
|
|
|||
Loading…
Reference in New Issue