suncalc

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2025 License: BSD-2-Clause Imports: 2 Imported by: 0

README

SunCalc 🌞

A lightweight Go library for calculating sun/moon positions and phases.

Overview

SunCalc is a BSD-licensed Go library that provides precise calculations for:

  • 🌅 Sun position and sunlight phases (sunrise, sunset, golden hour, etc.)
  • 🌙 Moon position and lunar phase
  • ⏱️ Time-based calculations for astronomical events

Originally created in JavaScript by Vladimir Agafonkin (@mourner) as part of the SunCalc.net project, and translated to Go by Douglas Six.

Installation

go get github.com/kixorz/suncalc

Usage Examples

Basic Usage
package main

import (
    "fmt"
    "time"
    "github.com/kixorz/suncalc"
)

func main() {
    // Example coordinates (latitude, longitude)
    lat, lng := 51.5, -0.1  // London
    
    // Get today's sunlight times
    now := time.Now()
    times := suncalc.GetTimes(now, lat, lng, 0, time.UTC)
    
    // Print sunrise and sunset times
    fmt.Printf("Sunrise: %s\n", times[suncalc.Sunrise].Value.Format("15:04:05"))
    fmt.Printf("Sunset: %s\n", times[suncalc.Sunset].Value.Format("15:04:05"))
    
    // Get current sun position
    pos := suncalc.GetPosition(now, lat, lng)
    fmt.Printf("Sun altitude: %.2f°, azimuth: %.2f°\n", 
        pos.Altitude * 180 / math.Pi, 
        pos.Azimuth * 180 / math.Pi)
}
Using SunCalculator

The SunCalculator provides a simpler API for day phase calculations:

// Create a calculator for a specific location and time
sc := suncalc.NewSunCalculator(latitude, longitude, time.Now())

// Get the current phase of the day
phase := sc.GetCurrentPhase()
fmt.Printf("Current phase: %s\n", phase)

// Check if it's currently day or night
if sc.IsDay() {
    fmt.Println("It's daytime!")
} else if sc.IsNight() {
    fmt.Println("It's nighttime!")
}

// Get moon illumination
moonIllum := sc.GetMoonIllumination()
fmt.Printf("Moon illumination: %.1f%%\n", moonIllum.Fraction * 100)

Features

Sun Calculations
  • Sun Position: Get altitude and azimuth for any location and time
  • Sunlight Phases: Calculate precise times for:
    • 🌄 Sunrise and sunset
    • ✨ Golden hour (soft light ideal for photography)
    • 🌆 Civil, nautical, and astronomical twilight
    • ☀️ Solar noon and nadir
Moon Calculations
  • Moon Position: Get altitude, azimuth, and distance
  • Moon Illumination: Calculate phase and illuminated fraction
  • Moon Times: Calculate moonrise and moonset times

API Reference

Sun Times
suncalc.GetTimes(date time.Time, latitude float64, longitude float64, height float64, location *time.Location)

Returns a map with the following properties (each is a DayTime object):

Property Description
Sunrise Sunrise (top edge of the sun appears on the horizon)
SunriseEnd Sunrise ends (bottom edge of the sun touches the horizon)
GoldenHourEnd Morning golden hour ends
SolarNoon Solar noon (sun is in the highest position)
GoldenHour Evening golden hour starts
SunsetStart Sunset starts (bottom edge of the sun touches the horizon)
Sunset Sunset (sun disappears below the horizon)
Dusk Dusk (evening nautical twilight starts)
NauticalDusk Nautical dusk (evening astronomical twilight starts)
Night Night starts (dark enough for astronomical observations)
Nadir Nadir (darkest moment of the night)
NightEnd Night ends (morning astronomical twilight starts)
NauticalDawn Nautical dawn (morning nautical twilight starts)
Dawn Dawn (morning civil twilight starts)
Binary Phase Methods

The SunCalculator provides binary methods to easily check if the current time is in a specific phase:

Method Description
IsNight() Returns true if current time is during night (sun is more than 18° below horizon)
IsAstroDawn() Returns true if current time is during astronomical dawn (sun is between 18° and 12° below horizon)
IsNauticalDawn() Returns true if current time is during nautical dawn (sun is between 12° and 6° below horizon)
IsCivilDawn() Returns true if current time is during civil dawn (sun is between 6° below horizon and sunrise)
IsSunrise() Returns true if current time is during sunrise (sun is rising above the horizon)
IsGoldenMorning() Returns true if current time is during morning golden hour
IsDay() Returns true if current time is during full daylight
IsGoldenEvening() Returns true if current time is during evening golden hour
IsSunset() Returns true if current time is during sunset (sun is setting below the horizon)
IsCivilDusk() Returns true if current time is during civil dusk (sun is between sunset and 6° below horizon)
IsNauticalDusk() Returns true if current time is during nautical dusk (sun is between 6° and 12° below horizon)
IsAstroDusk() Returns true if current time is during astronomical dusk (sun is between 12° and 18° below horizon)

License

BSD License

Credits

Documentation

Index

Constants

View Source
const J0 = 0.0009

calculations for sun times

View Source
const J1970 = 2440588
View Source
const J2000 = 2451545

Variables

Functions

func GetTimes

func GetTimes(date time.Time, lat float64, lng float64) map[DayTimeName]DayTime

calculates sun times for a given date and latitude/longitude

func GetTimesWithObserver

func GetTimesWithObserver(date time.Time, obs Observer) map[DayTimeName]DayTime

calculates sun times for a given date and latitude/longitude, and, the observer height (in meters) relative to the horizon, you can set it to 0 if unknown

Types

type DayPhase

type DayPhase string

DayPhase represents different phases of the day Each phase corresponds to a specific period of the day based on the sun's position

const (
	// PhaseNight represents full darkness when the sun is far below the horizon
	PhaseNight DayPhase = "night" // Full night time

	// PhaseAstroDawn represents the period when the sun is between 18° and 12° below the horizon (morning)
	PhaseAstroDawn DayPhase = "astroDawn" // Astronomical dawn (night ends)

	// PhaseNauticalDawn represents the period when the sun is between 12° and 6° below the horizon (morning)
	PhaseNauticalDawn DayPhase = "nauticalDawn" // Nautical dawn

	// PhaseCivilDawn represents the period when the sun is between 6° below the horizon and sunrise (morning twilight)
	PhaseCivilDawn DayPhase = "civilDawn" // Civil dawn (morning twilight)

	// PhaseSunrise represents the period when the sun is rising above the horizon
	PhaseSunrise DayPhase = "sunrise" // Sunrise period

	// PhaseGoldenMorning represents the period shortly after sunrise with soft, warm light (morning golden hour)
	PhaseGoldenMorning DayPhase = "goldenMorning" // Morning golden hour

	// PhaseDay represents the period of full daylight between the golden hours
	PhaseDay DayPhase = "day" // Full daylight

	// PhaseGoldenEvening represents the period shortly before sunset with soft, warm light (evening golden hour)
	PhaseGoldenEvening DayPhase = "goldenEvening" // Evening golden hour

	// PhaseSunset represents the period when the sun is setting below the horizon
	PhaseSunset DayPhase = "sunset" // Sunset period

	// PhaseCivilDusk represents the period when the sun is between sunset and 6° below the horizon (evening twilight)
	PhaseCivilDusk DayPhase = "civilDusk" // Civil dusk (evening twilight)

	// PhaseNauticalDusk represents the period when the sun is between 6° and 12° below the horizon (evening)
	PhaseNauticalDusk DayPhase = "nauticalDusk" // Nautical dusk

	// PhaseAstroDusk represents the period when the sun is between 12° and 18° below the horizon (evening)
	PhaseAstroDusk DayPhase = "astroDusk" // Astronomical dusk (night starts)
)

type DayTime

type DayTime struct {
	Name  DayTimeName
	Value time.Time
}

type DayTimeName

type DayTimeName string
const (
	Sunrise DayTimeName = "sunrise" // sunrise (top edge of the sun appears on the horizon)
	Sunset  DayTimeName = "sunset"  // sunset (sun disappears below the horizon, evening civil twilight starts)

	SunriseEnd  DayTimeName = "sunriseEnd"  // sunrise ends (bottom edge of the sun touches the horizon)
	SunsetStart DayTimeName = "sunsetStart" // sunset starts (bottom edge of the sun touches the horizon)

	Dawn DayTimeName = "dawn" // dawn (morning nautical twilight ends, morning civil twilight starts)
	Dusk DayTimeName = "dusk" // dusk (evening nautical twilight starts)

	NauticalDawn DayTimeName = "nauticalDawn" // nautical dawn (morning nautical twilight starts)
	NauticalDusk DayTimeName = "nauticalDusk" // nautical dusk (evening astronomical twilight starts)

	NightEnd DayTimeName = "nightEnd" // night ends (morning astronomical twilight starts)
	Night    DayTimeName = "night"    // night starts (dark enough for astronomical observations)

	GoldenHourEnd DayTimeName = "goldenHourEnd" // morning golden hour (soft light, best DayTime for photography) ends
	GoldenHour    DayTimeName = "goldenHour"    // evening golden hour starts

	SolarNoon DayTimeName = "solarNoon" // solar noon (sun is in the highest position)
	Nadir     DayTimeName = "nadir"     // nadir (darkest moment of the night, sun is in the lowest position)
)

type MoonIllumination

type MoonIllumination struct {
	Fraction float64
	Phase    float64
	Angle    float64
}

func GetMoonIllumination

func GetMoonIllumination(date time.Time) MoonIllumination

calculations for illumination parameters of the moon, based on http://idlastro.gsfc.nasa.gov/ftp/pro/astro/mphase.pro formulas and Chapter 48 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998.

type MoonPosition

type MoonPosition struct {
	Azimuth          float64
	Altitude         float64
	Distance         float64
	ParallacticAngle float64
}

func GetMoonPosition

func GetMoonPosition(date time.Time, lat float64, lng float64) MoonPosition

type MoonTimes

type MoonTimes struct {
	Rise       time.Time
	Set        time.Time
	AlwaysUp   bool
	AlwaysDown bool
}

func GetMoonTimes

func GetMoonTimes(date time.Time, lat float64, lng float64) MoonTimes

calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article

func GetMoonTimesWithObserver

func GetMoonTimesWithObserver(date time.Time, obs Observer) MoonTimes

calculations for moon rise/set times are based on http://www.stargazing.net/kepler/moonrise.html article

type Observer

type Observer struct {
	// Location of the observer
	Latitude, Longitude,

	Height float64

	Location *time.Location
}

type SunCalculator

type SunCalculator struct {
	// contains filtered or unexported fields
}

SunCalculator provides methods to determine sun positions and day phases It wraps the suncalc library to provide a simpler API for day phase calculations and binary getter methods for each phase.

func NewSunCalculator

func NewSunCalculator(latitude, longitude float64, date time.Time) *SunCalculator

NewSunCalculator creates a new SunCalculator for the given coordinates and date Parameters:

  • latitude: Latitude in decimal degrees (positive for north, negative for south)
  • longitude: Longitude in decimal degrees (positive for east, negative for west)
  • date: Date for which to calculate sun times (the time component is used for the day)

Returns a pointer to a new SunCalculator with pre-calculated sun times for the specified day

func (*SunCalculator) GetAllTimes

func (sc *SunCalculator) GetAllTimes() map[DayTimeName]DayTime

GetAllTimes returns all calculated sun times for the day This provides access to the raw sun times calculated by the suncalc library

func (*SunCalculator) GetCurrentPhase

func (sc *SunCalculator) GetCurrentPhase() DayPhase

GetCurrentPhase determines the current day phase based on the current time This method compares the current time with the pre-calculated sun times to determine which phase of the day it currently is.

Returns a DayPhase constant representing the current phase of the day

func (*SunCalculator) GetMoonIllumination

func (sc *SunCalculator) GetMoonIllumination(t ...time.Time) MoonIllumination

GetMoonIllumination returns information about the moon's illumination for the given time If no time is provided, it uses the current time Returns an object with Fraction, Phase, and Angle properties

func (*SunCalculator) GetMoonPosition

func (sc *SunCalculator) GetMoonPosition(t ...time.Time) MoonPosition

GetMoonPosition returns the position of the moon for the given time If no time is provided, it uses the current time Returns an object with Altitude, Azimuth, Distance and ParallacticAngle properties

func (*SunCalculator) GetMoonTimes

func (sc *SunCalculator) GetMoonTimes(date time.Time) MoonTimes

GetMoonTimes returns the moon rise and set times for the given date If no date is provided, it uses the current date If inUTC is true, it will search the specified date from 0 to 24 UTC hours Returns an object with Rise, Set, AlwaysUp, and AlwaysDown properties

func (*SunCalculator) GetSunPosition

func (sc *SunCalculator) GetSunPosition(t ...time.Time) SunPosition

GetSunPosition returns the position of the sun (azimuth and altitude) for the given time If no time is provided, it uses the current time Returns an object with Azimuth and Altitude properties in radians

func (*SunCalculator) IsAstroDawn

func (sc *SunCalculator) IsAstroDawn() bool

IsAstroDawn returns true if current time is during astronomical dawn Astronomical dawn is when the sun is between 18° and 12° below the horizon in the morning

func (*SunCalculator) IsAstroDusk

func (sc *SunCalculator) IsAstroDusk() bool

IsAstroDusk returns true if current time is during astronomical dusk Astronomical dusk is when the sun is between 12° and 18° below the horizon in the evening

func (*SunCalculator) IsCivilDawn

func (sc *SunCalculator) IsCivilDawn() bool

IsCivilDawn returns true if current time is during civil dawn Civil dawn is when the sun is between 6° below the horizon and sunrise

func (*SunCalculator) IsCivilDusk

func (sc *SunCalculator) IsCivilDusk() bool

IsCivilDusk returns true if current time is during civil dusk Civil dusk is when the sun is between sunset and 6° below the horizon

func (*SunCalculator) IsDay

func (sc *SunCalculator) IsDay() bool

IsDay returns true if current time is during full daylight Day is the period of full daylight between the golden hours

func (*SunCalculator) IsGoldenEvening

func (sc *SunCalculator) IsGoldenEvening() bool

IsGoldenEvening returns true if current time is during evening golden hour Evening golden hour is the period shortly before sunset with soft, warm light

func (*SunCalculator) IsGoldenMorning

func (sc *SunCalculator) IsGoldenMorning() bool

IsGoldenMorning returns true if current time is during morning golden hour Morning golden hour is the period shortly after sunrise with soft, warm light

func (*SunCalculator) IsNauticalDawn

func (sc *SunCalculator) IsNauticalDawn() bool

IsNauticalDawn returns true if current time is during nautical dawn Nautical dawn is when the sun is between 12° and 6° below the horizon in the morning

func (*SunCalculator) IsNauticalDusk

func (sc *SunCalculator) IsNauticalDusk() bool

IsNauticalDusk returns true if current time is during nautical dusk Nautical dusk is when the sun is between 6° and 12° below the horizon in the evening

func (*SunCalculator) IsNight

func (sc *SunCalculator) IsNight() bool

IsNight returns true if current time is during night Night is the period when the sun is far below the horizon (more than 18°)

func (*SunCalculator) IsSunrise

func (sc *SunCalculator) IsSunrise() bool

IsSunrise returns true if current time is during sunrise Sunrise is the period when the sun is rising above the horizon

func (*SunCalculator) IsSunset

func (sc *SunCalculator) IsSunset() bool

IsSunset returns true if current time is during sunset Sunset is the period when the sun is setting below the horizon

type SunPosition

type SunPosition struct {
	Azimuth  float64
	Altitude float64
}

func GetPosition

func GetPosition(date time.Time, lat float64, lng float64) SunPosition

calculates sun position for a given date and latitude/longitude

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL