Get The Sunrise And Sunset Times For A Specific Location In Rust Including Daylight Saving Time
---
[dependencies]
chrono = "0.4.39"
chrono-tz = "0.10.0"
lazy_static = "1.5.0"
sunrise = "1.0.1"
tzf-rs = "0.4.9"
---
use chrono::DateTime;
use chrono_tz::Tz;
use lazy_static::lazy_static;
use sunrise::sunrise_sunset;
use tzf_rs::DefaultFinder;
lazy_static! {
static ref FINDER: DefaultFinder = DefaultFinder::new();
}
fn main() {
let lat = 30.332184;
let long = -81.655647;
println!(
"Daylight Time Sunrise Example: {}",
sunrise_for_lat_long(lat, long, 2024, 11, 2)
);
println!(
"Daylight Time Sunset Example: {}",
sunset_for_lat_long(lat, long, 2024, 11, 2)
);
println!(
"Standard Sunrise Time Example: {}",
sunrise_for_lat_long(lat, long, 2024, 11, 3)
);
println!(
"Standard Sunset Time Example: {}",
sunset_for_lat_long(lat, long, 2024, 11, 3)
);
}
fn sunrise_for_lat_long(lat: f64, long: f64, year: i32, month: u32, day: u32) -> DateTime<Tz> {
let tz: Tz = FINDER.get_tz_name(long, lat).parse().unwrap();
let (sunrise_ts, _) = sunrise_sunset(
lat, long, year, month, day
);
let dt = DateTime::from_timestamp(sunrise_ts, 0).expect("invalid timestamp").with_timezone(&tz);
dt
}
fn sunset_for_lat_long(lat: f64, long: f64, year: i32, month: u32, day: u32) -> DateTime<Tz> {
let tz: Tz = FINDER.get_tz_name(long, lat).parse().unwrap();
let (_, sunset_ts) = sunrise_sunset(
lat, long, year, month, day
);
let dt = DateTime::from_timestamp(sunset_ts, 0).expect("invalid timestamp").with_timezone(&tz);
dt
}
Output:
Daylight Time Sunrise Example: 2024-11-02 07:42:04 EDT
Daylight Time Sunset Example: 2024-11-02 18:38:12 EDT
Standard Sunrise Time Example: 2024-11-03 06:42:52 EST
Standard Sunset Time Example: 2024-11-03 17:37:26 EST
Notes
- This code panics if there's an issue (i.e. error handling could be improved)
- Handles daylight saving time changes
-
From what I can tell it's not necessary to convert the date into UTC before running the
sunrise_sunset
function. There might be a use case though based on some time zones where that would be necessary, but I haven't figured out that edge case yet if it exists.
-- end of line --
References
-
The crate that does the main date handling
-
The crate that allows using named time zones for chrono's
DateTime
-
A macro crate that helps speed up searching for time zones in
chrono_tz
when multiple searches are needed -
The crate that does the calculation for sunrise and sunset given a specific lat/long
-
The create the provides time zones for specific lat/long coordinates