sun_times
Version, currently 0.1.02 versions
- 0.2.0latestJul 7, 2026
- 0.1.0not indexedJul 13, 2026
github.com/geocrystal/sun_times
Simple Crystal library for calculating sunrise and sunset given latitude, longitude, and date
Nothing has been indexed for 0.1.0 yet. The tag is recorded, its shard.yml has not been read, so the manifest and dependency list below are empty because they are unknown rather than because they are absent.
Installation
# Add this to your shard.yml
dependencies:
sun_times:
github: geocrystal/sun_times
version: ~> 0.1.0Then run:
shards installshard.yml
No shard.yml has been indexed for 0.1.0. You can read it on the repository.
Dependencies
Unknown: the shard.yml for this version has not been read yet.
README
This README is the one indexed from the repository at its latest ref, not from the tag for this version.
☀️ sun_times
A simple Crystal library for calculating 🌅 sunrise and 🌇 sunset given latitude, longitude, and date based on the NOAA Solar Calculator and formulas from Jean Meeus' Astronomical Algorithms (2nd Edition, 1998).
📊 Accuracy
The library's astronomical constants and algorithms follow authoritative sources (NOAA, JPL, Meeus) and were verified manually against the NOAA Solar Calculator (https://gml.noaa.gov/grad/solcalc/).
Verification
- A validation script (
samples/accuracy_check.cr) compares calculated sunrise, sunset and solar noon against NOAA's apparent times for several locations. - The comparison was performed manually by running the script and checking the NOAA site for reference values.
Results
- Calculated times are within the margin of error and are effectively identical to NOAA's apparent times. Differences are typically under 1 minute.
- Tested locations include New York, London, Tokyo and Sydney. Example: New York on 2025-11-05 matched NOAA apparent sunrise/sunset closely (06:31 / 16:47 local).
📦 Installation
-
Add the dependency to your
shard.yml:dependencies: sun_times: github: geocrystal/sun_times -
Run
shards install
💻 Usage
require "sun_times"
# Example: Lviv, Ukraine
# SunTime.new(latitude : Float64, longitude : Float64)
sun = SunTimes::SunTime.new(49.8419, 24.0311)
location = Time::Location.load("Europe/Kyiv")
date = Time.local
astronomical_dawn_time = sun.astronomical_dawn(date, location)
nautical_dawn_time = sun.nautical_dawn(date, location)
civil_dawn_time = sun.civil_dawn(date, location)
sunrise_time = sun.sunrise(date, location)
solar_noon_time = sun.solar_noon(date, location)
sunset_time = sun.sunset(date, location)
civil_dusk_time = sun.civil_dusk(date, location)
nautical_dusk_time = sun.nautical_dusk(date, location)
astronomical_dusk_time = sun.astronomical_dusk(date, location)
daylight_length = sun.daylight_length(date, location)
puts "Timezone: #{location}"
puts "Now: #{date}"
puts
puts "=== Twilight Periods ==="
puts "Astronomical dawn: #{astronomical_dawn_time}"
puts "Nautical dawn: #{nautical_dawn_time}"
puts "Civil dawn: #{civil_dawn_time}"
puts "Sunrise: #{sunrise_time}"
puts "Solar noon: #{solar_noon_time}"
puts "Sunset: #{sunset_time}"
puts "Civil dusk: #{civil_dusk_time}"
puts "Nautical dusk: #{nautical_dusk_time}"
puts "Astronomical dusk: #{astronomical_dusk_time}"
puts ""
puts "=== Daylight ==="
puts "Daylight: #{daylight_length}"
Latitude must be between -90.0 and 90.0 degrees. Longitude must be between
-180.0 and 180.0 degrees. Invalid coordinates raise
SunTimes::InvalidInputError.
In polar regions, sunrise and sunset may not occur on a given date. The raising
methods (sunrise, sunset, and twilight methods) raise
SunTimes::CalculationError when the event does not occur. The non-raising
variants (sunrise?, sunset?, and twilight ? methods) return nil.
daylight_length returns 24.hours for polar day and Time::Span.zero for
polar night.
Output:
Timezone: Europe/Kyiv
Now: 2025-11-05 14:05:23 +02:00
=== Twilight Periods ===
Astronomical dawn: 2025-11-05 05:30:09 +02:00
Nautical dawn: 2025-11-05 06:07:40 +02:00
Civil dawn: 2025-11-05 06:46:02 +02:00
Sunrise: 2025-11-05 07:20:19 +02:00
Solar noon: 2025-11-05 12:07:24 +02:00
Sunset: 2025-11-05 16:54:29 +02:00
Civil dusk: 2025-11-05 17:28:46 +02:00
Nautical dusk: 2025-11-05 18:07:08 +02:00
Astronomical dusk: 2025-11-05 18:44:39 +02:00
=== Daylight ===
Daylight: 9h 34m 9s

You can also get all solar events as a NamedTuple using the events method, which is useful for serialization (e.g., JSON): 📋
require "json"
require "sun_times"
sun = SunTimes::SunTime.new(49.8419, 24.0311)
location = Time::Location.load("Europe/Kyiv")
date = Time.local
sun.events(date, location).to_json
Output
{
"astronomical_dawn":"2025-11-05T05:30:09+02:00",
"nautical_dawn":"2025-11-05T06:07:40+02:00",
"civil_dawn":"2025-11-05T06:46:02+02:00",
"sunrise":"2025-11-05T07:20:19+02:00",
"solar_noon":"2025-11-05T12:07:24+02:00",
"sunset":"2025-11-05T16:54:29+02:00",
"civil_dusk":"2025-11-05T17:28:46+02:00",
"nautical_dusk":"2025-11-05T18:07:08+02:00",
"astronomical_dusk":"2025-11-05T18:44:39+02:00"
}
🌆 Twilight Periods
The library supports three types of twilight periods:
- Civil twilight 🌅 (sun 6° below horizon): Enough light for most outdoor activities
- Nautical twilight ⚓ (sun 12° below horizon): Horizon is still visible for navigation
- Astronomical twilight 🔭 (sun 18° below horizon): Sky is dark enough for astronomical observations

🚀 Performance
The library is fast as the speed of light! ⚡ Individual calculations are sub-microsecond, and the events method that computes all solar events is still under 4 microseconds per call.
Benchmark results were obtained on Intel(R) Core(TM) i7-8550U (8) @ 4.00 GHz.
You can run the benchmark with:
crystal run --release samples/benchmark.cr
🤝 Contributing
- Fork it (https://github.com/geocrystal/sun_times/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
👥 Contributors
- Anton Maminov - creator and maintainer
📄 License
This library is distributed under the MIT license. Please see the LICENSE file.
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This release
- Version
0.1.0- Tagged
- Jul 13, 2026
- Commit
a3e99d2b1104- Indexed
- not yet
Dependents
Repository
github.com/geocrystal/sun_times
Metadata
- Created
- Aug 16, 2026
- Updated
- Sep 24, 2026
- Synced
- Sep 24, 2026
- Versions
- 2