mirror of https://github.com/vinc/moros.git
46 lines
1.4 KiB
Rust
46 lines
1.4 KiB
Rust
use crate::api::clock;
|
|
use crate::api::process::ExitCode;
|
|
|
|
use alloc::format;
|
|
use core::f64::consts::PI;
|
|
|
|
pub fn main(args: &[&str]) -> Result<(), ExitCode> {
|
|
if args.len() < 2 {
|
|
eprintln!("Usage: <longitude> [<timestamp>]");
|
|
return Err(ExitCode::UsageError);
|
|
}
|
|
|
|
let longitude = args[1].parse().expect("Could not parse longitude");
|
|
|
|
let timestamp = if args.len() == 3 {
|
|
args[2].parse().expect("Could not parse timestamp")
|
|
} else {
|
|
clock::realtime()
|
|
};
|
|
|
|
let t = geotime(longitude, timestamp);
|
|
let t = libm::floor(100.0 * t) / 100.0; // Avoid rounding up 99.996 to 100.00
|
|
println!("{}", format!("{:05.2}", t).replace(".", ":"));
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn geotime(longitude: f64, timestamp: f64) -> f64 {
|
|
let days = libm::floor(libm::fmod(timestamp / 86400.0, 365.2425));
|
|
let hours = libm::floor(libm::fmod(timestamp, 86400.0) / 3600.0);
|
|
|
|
// Equation of time (https://www.esrl.noaa.gov/gmd/grad/solcalc/solareqns.PDF)
|
|
let y = (2.0 * PI / 365.0) * (days + (hours - 12.0) / 24.0);
|
|
let eot = 60.0 * 229.18 * (
|
|
0.000075 +
|
|
0.001868 * libm::cos(1.0 * y) -
|
|
0.032077 * libm::sin(1.0 * y) -
|
|
0.014615 * libm::cos(2.0 * y) -
|
|
0.040849 * libm::sin(2.0 * y)
|
|
);
|
|
|
|
let seconds = libm::fmod(timestamp, 86400.0) + (longitude * 86400.0 / 360.0) + eot;
|
|
|
|
libm::fmod(100.0 * seconds / 86400.0, 100.0)
|
|
}
|