Function sun_angles() returns the solar angles and Sun to Earth
relative distance for given times and locations using a very accurate
algorithm. Convenience functions sun_azimuth(),
sun_elevation(), sun_zenith_angle() and
distance_to_sun() are wrappers on sun_angles() that return
individual vectors.
Usage
sun_angles(
  time = lubridate::now(tzone = "UTC"),
  tz = lubridate::tz(time),
  geocode = tibble::tibble(lon = 0, lat = 51.5, address = "Greenwich"),
  use.refraction = FALSE
)
sun_angles_fast(time, tz, geocode, use.refraction)
sun_elevation(
  time = lubridate::now(),
  tz = lubridate::tz(time),
  geocode = tibble::tibble(lon = 0, lat = 51.5, address = "Greenwich"),
  use.refraction = FALSE
)
sun_zenith_angle(
  time = lubridate::now(),
  tz = lubridate::tz(time),
  geocode = tibble::tibble(lon = 0, lat = 51.5, address = "Greenwich"),
  use.refraction = FALSE
)
sun_azimuth(
  time = lubridate::now(),
  tz = lubridate::tz(time),
  geocode = tibble::tibble(lon = 0, lat = 51.5, address = "Greenwich"),
  use.refraction = FALSE
)
distance_to_sun(
  time = lubridate::now(),
  tz = lubridate::tz(time),
  geocode = tibble::tibble(lon = 0, lat = 51.5, address = "Greenwich"),
  use.refraction = FALSE
)Arguments
- time
- A "vector" of POSIXct Time, with any valid time zone (TZ) is allowed, default is current time. 
- tz
- character string indicating time zone to be used in output. 
- geocode
- data frame with variables lon and lat as numeric values (degrees), nrow > 1, allowed. 
- use.refraction
- logical Flag indicating whether to correct for fraction in the atmosphere. 
Value
A data.frame with variables time (in same TZ as input),
  TZ, solartime, longitude, latitude,
  address, azimuth, elevation, declination,
  eq.of.time, hour.angle, and distance. If a data frame
  with multiple rows is passed to geocode and a vector of times longer
  than one is passed to time, sun position for all combinations of
  locations and times are returned by sun_angles. Angles are expressed
  in degrees, solartime is a vector of class "solar.time",
  distance is expressed in relative sun units.
Details
This function is an implementation of Meeus equations as used in NOAA's on-line web calculator, which are precise and valid for a very broad range of dates (years -1000 to 3000 at least). The apparent solar elevations near sunrise and sunset are affected by refraction in the atmosphere, which does in turn depend on weather conditions. The effect of refraction on the apparent position of the sun is only an estimate based on "typical" conditions for the atmosphere. The computation is not defined for latitudes 90 and -90 degrees, i.e. exactly at the poles. The function is vectorized and in particular passing a vector of times for a single geocode enhances performance very much as the equation of time, the most time consuming step, is computed only once.
For improved performance, if more than one angle is needed it
  is preferable to directly call sun_angles instead of the wrapper
  functions as this avoids the unnecesary recalculation.
Note
There exists a different R implementation of the same algorithms called
  "AstroCalcPureR" available as function astrocalc4r in package
  'fishmethods'. Although the equations used are almost all the same, the
  function signatures and which values are returned differ. In particular,
  the present implementation splits the calculation into two separate
  functions, one returning angles at given instants in time, and a separate
  one returning the timing of events for given dates.
Important!
Given an instant in time and a time zone, the date is
  computed from these, and may differ by one day to that at the location
  pointed by geocode at the same instant in time, unless the argument
  passed to tz matches the time zone at this location.
References
The primary source for the algorithm used is the book: Meeus, J. (1998) Astronomical Algorithms, 2 ed., Willmann-Bell, Richmond, VA, USA. ISBN 978-0943396613.
A different implementation is available at https://github.com/NEFSC/READ-PDB-AstroCalc4R/.
An interactive web page using the same algorithms is available at https://gml.noaa.gov/grad/solcalc/. There are small differences in the returned times compared to our function that seem to be related to the estimation of atmospheric refraction (about 0.1 degrees).
See also
Other astronomy related functions:
day_night(),
format.solar_time()
Examples
library(lubridate)
sun_angles()
#> # A tibble: 1 × 12
#>   time                tz    solartime  longitude latitude address   azimuth
#>   <dttm>              <chr> <solar_tm>     <dbl>    <dbl> <chr>       <dbl>
#> 1 2025-10-02 21:56:07 UTC   22:06:58           0     51.5 Greenwich    324.
#> # ℹ 5 more variables: elevation <dbl>, declination <dbl>, eq.of.time <dbl>,
#> #   hour.angle <dbl>, distance <dbl>
sun_azimuth()
#> [1] 323.7837
sun_elevation()
#> [1] -36.93218
sun_zenith_angle()
#> [1] 126.9322
sun_angles(ymd_hms("2014-09-23 12:00:00"))
#> # A tibble: 1 × 12
#>   time                tz    solartime  longitude latitude address   azimuth
#>   <dttm>              <chr> <solar_tm>     <dbl>    <dbl> <chr>       <dbl>
#> 1 2014-09-23 12:00:00 UTC   12:07:35           0     51.5 Greenwich    182.
#> # ℹ 5 more variables: elevation <dbl>, declination <dbl>, eq.of.time <dbl>,
#> #   hour.angle <dbl>, distance <dbl>
sun_angles(ymd_hms("2014-09-23 12:00:00"),
           geocode = data.frame(lat=60, lon=0))
#> # A tibble: 1 × 12
#>   time                tz    solartime  longitude latitude address azimuth
#>   <dttm>              <chr> <solar_tm>     <dbl>    <dbl> <chr>     <dbl>
#> 1 2014-09-23 12:00:00 UTC   12:07:35           0       60 NA         182.
#> # ℹ 5 more variables: elevation <dbl>, declination <dbl>, eq.of.time <dbl>,
#> #   hour.angle <dbl>, distance <dbl>
sun_angles(ymd_hms("2014-09-23 12:00:00") + minutes((0:6) * 10))
#> # A tibble: 7 × 12
#>   time                tz    solartime  longitude latitude address   azimuth
#>   <dttm>              <chr> <solar_tm>     <dbl>    <dbl> <chr>       <dbl>
#> 1 2014-09-23 12:00:00 UTC   12:07:35           0     51.5 Greenwich    182.
#> 2 2014-09-23 12:10:00 UTC   12:17:35           0     51.5 Greenwich    186.
#> 3 2014-09-23 12:20:00 UTC   12:27:35           0     51.5 Greenwich    189.
#> 4 2014-09-23 12:30:00 UTC   12:37:35           0     51.5 Greenwich    192.
#> 5 2014-09-23 12:40:00 UTC   12:47:35           0     51.5 Greenwich    195.
#> 6 2014-09-23 12:50:00 UTC   12:57:35           0     51.5 Greenwich    198.
#> 7 2014-09-23 13:00:00 UTC   13:07:36           0     51.5 Greenwich    201.
#> # ℹ 5 more variables: elevation <dbl>, declination <dbl>, eq.of.time <dbl>,
#> #   hour.angle <dbl>, distance <dbl>
