use chrono::{ prelude::{Local, Utc}, TimeZone, Timelike, }; use suncalc::SunTimes; use crate::config::Config; const HOUR_NAMES: [&str; 24] = [ "Candle", "Ice", "Comet", "Thimble", "Root", "Mist", "Sprout", "Rainbow", "Worm", "Bud", "Blossom", "Ladybug", "Geese", "Dust", "Peach", "Fog", "Acorn", "Gourd", "Soup", "Crow", "Mushroom", "Thunder", "Frost", "Lantern", ]; pub enum DayPart { LocalNow, UtcNow, UtcNoon, UtcMidnight, UtcMorningGoldenEnd, UtcEveningGoldenStart, UtcSunrise, UtcSunset, UtcDawnStart, UtcDuskEnd, } pub fn get_moon_phase() -> f32 { let local_timestamp = Local::now(); let unixtime = suncalc::Timestamp(local_timestamp.timestamp_millis()); let moon_illumination = suncalc::moon_illumination(unixtime); moon_illumination.phase as f32 * 28.0 } pub fn get_seconds_since_midnight(config: &Option, which: DayPart) -> i32 { let local_timestamp = Local::now(); let unixtime = suncalc::Timestamp(local_timestamp.timestamp_millis()); let sun_times: Option = if config.is_some() { Some(suncalc::get_times( unixtime, config.unwrap().latitude, config.unwrap().longitude, None, )) } else { None }; let seconds = match which { DayPart::LocalNow => local_timestamp.time().num_seconds_from_midnight(), DayPart::UtcNow => local_timestamp .with_timezone(&Utc) .time() .num_seconds_from_midnight(), DayPart::UtcNoon => Utc .timestamp_millis(sun_times.unwrap().solar_noon.0) .time() .num_seconds_from_midnight(), DayPart::UtcMidnight => Utc .timestamp_millis(sun_times.unwrap().nadir.0) .time() .num_seconds_from_midnight(), DayPart::UtcMorningGoldenEnd => Utc .timestamp_millis(sun_times.unwrap().golden_hour_end.0) .time() .num_seconds_from_midnight(), DayPart::UtcEveningGoldenStart => Utc .timestamp_millis(sun_times.unwrap().golden_hour.0) .time() .num_seconds_from_midnight(), DayPart::UtcSunrise => Utc .timestamp_millis(sun_times.unwrap().sunrise.0) .time() .num_seconds_from_midnight(), DayPart::UtcSunset => Utc .timestamp_millis(sun_times.unwrap().sunset.0) .time() .num_seconds_from_midnight(), DayPart::UtcDawnStart => Utc .timestamp_millis(sun_times.unwrap().dawn.0) .time() .num_seconds_from_midnight(), DayPart::UtcDuskEnd => Utc .timestamp_millis(sun_times.unwrap().dusk.0) .time() .num_seconds_from_midnight(), }; seconds as i32 } pub fn get_hms(config: &Option, which: DayPart) -> (u8, u8, u8) { let mut seconds = get_seconds_since_midnight(config, which); let hours = seconds / 3600; seconds -= hours * 3600; let minutes = seconds / 60; seconds -= minutes * 60; (hours as u8, minutes as u8, seconds as u8) } pub fn get_utc_offset() -> i32 { Local::now().offset().local_minus_utc() } pub fn get_utc_hour_name(hour: usize) -> &'static str { HOUR_NAMES[hour] } pub fn get_current_hour_name() -> &'static str { let (utc_hour, _, _) = get_hms(&None, DayPart::UtcNow); get_utc_hour_name(utc_hour as usize) }