---
name: r.sunhours
description: Calculates solar elevation, solar azimuth, and sun hours. Solar elevation: the angle between the direction of the geometric center of the sun's apparent disk and the (idealized) horizon. Solar azimuth: the angle from due north in clockwise direction.
keywords: [ raster, solar, sun energy, sun position ]
---

# r.sunhours

Calculates solar elevation, solar azimuth, and sun hours.

Solar elevation: the angle between the direction of the geometric center of the sun's apparent disk and the (idealized) horizon. Solar azimuth: the angle from due north in clockwise direction.

=== "Command line"

    **r.sunhours**
    [**-ts**]
    [**elevation**=*name*]
    [**azimuth**=*name*]
    [**sunhour**=*name*]
    **year**=*integer*
    [**month**=*integer*]
    **day**=*integer*
    [**hour**=*integer*]
    [**minute**=*integer*]
    [**second**=*integer*]
    [**--overwrite**]
    [**--verbose**]
    [**--quiet**]
    [**--qq**]
    [**--ui**]

    Example:

    ```sh
    r.sunhours year=0 day=0
    ```

=== "Python (grass.tools)"

    *grass.tools.Tools.r_sunhours*(**elevation**=*None*,
        **azimuth**=*None*,
        **sunhour**=*None*,
        **year**,
        **month**=*None*,
        **day**,
        **hour**=*12*,
        **minute**=*0*,
        **second**=*0*,
        **flags**=*None*,
        **overwrite**=*None*,
        **verbose**=*None*,
        **quiet**=*None*,
        **superquiet**=*None*)

    Example:

    ```python
    tools = Tools()
    tools.r_sunhours(year=0, day=0)
    ```

    This grass.tools API is experimental in version 8.5 and expected to be stable in version 8.6.

=== "Python (grass.script)"

    *grass.script.run_command*("***r.sunhours***",
        **elevation**=*None*,
        **azimuth**=*None*,
        **sunhour**=*None*,
        **year**,
        **month**=*None*,
        **day**,
        **hour**=*12*,
        **minute**=*0*,
        **second**=*0*,
        **flags**=*None*,
        **overwrite**=*None*,
        **verbose**=*None*,
        **quiet**=*None*,
        **superquiet**=*None*)

    Example:

    ```python
    gs.run_command("r.sunhours", year=0, day=0)
    ```

## Parameters

=== "Command line"

    **elevation**=*name*  
    &nbsp;&nbsp;&nbsp;&nbsp;Output raster map with solar elevation angle  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output raster map  
    **azimuth**=*name*  
    &nbsp;&nbsp;&nbsp;&nbsp;Output raster map with solar azimuth angle  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output raster map  
    **sunhour**=*name*  
    &nbsp;&nbsp;&nbsp;&nbsp;Output raster map with sunshine hours  
    &nbsp;&nbsp;&nbsp;&nbsp;Sunshine hours require SOLPOS use and Greenwich standard time  
    **year**=*integer* **[required]**  
    &nbsp;&nbsp;&nbsp;&nbsp;Year  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *1950-2050*  
    **month**=*integer*  
    &nbsp;&nbsp;&nbsp;&nbsp;Month  
    &nbsp;&nbsp;&nbsp;&nbsp;If not given, day is interpreted as day of the year  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *1-12*  
    **day**=*integer* **[required]**  
    &nbsp;&nbsp;&nbsp;&nbsp;Day  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *1-366*  
    **hour**=*integer*  
    &nbsp;&nbsp;&nbsp;&nbsp;Hour  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *0-24*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *12*  
    **minute**=*integer*  
    &nbsp;&nbsp;&nbsp;&nbsp;Minutes  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *0-60*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *0*  
    **second**=*integer*  
    &nbsp;&nbsp;&nbsp;&nbsp;Seconds  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *0-60*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *0*  
    **-t**  
    &nbsp;&nbsp;&nbsp;&nbsp;Time is local sidereal time, not Greenwich standard time  
    **-s**  
    &nbsp;&nbsp;&nbsp;&nbsp;Do not use SOLPOS algorithm of NREL  
    **--overwrite**  
    &nbsp;&nbsp;&nbsp;&nbsp;Allow output files to overwrite existing files  
    **--help**  
    &nbsp;&nbsp;&nbsp;&nbsp;Print usage summary  
    **--verbose**  
    &nbsp;&nbsp;&nbsp;&nbsp;Verbose module output  
    **--quiet**  
    &nbsp;&nbsp;&nbsp;&nbsp;Quiet module output  
    **--qq**  
    &nbsp;&nbsp;&nbsp;&nbsp;Very quiet module output  
    **--ui**  
    &nbsp;&nbsp;&nbsp;&nbsp;Force launching GUI dialog

=== "Python (grass.tools)"

    **elevation** : str | type(np.ndarray) | type(np.array) | type(gs.array.array), *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Output raster map with solar elevation angle  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output raster map  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, raster, *name*  
    **azimuth** : str | type(np.ndarray) | type(np.array) | type(gs.array.array), *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Output raster map with solar azimuth angle  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output raster map  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, raster, *name*  
    **sunhour** : str | type(np.ndarray) | type(np.array) | type(gs.array.array), *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Output raster map with sunshine hours  
    &nbsp;&nbsp;&nbsp;&nbsp;Sunshine hours require SOLPOS use and Greenwich standard time  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, raster, *name*  
    **year** : int, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Year  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *1950-2050*  
    **month** : int, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Month  
    &nbsp;&nbsp;&nbsp;&nbsp;If not given, day is interpreted as day of the year  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *1-12*  
    **day** : int, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Day  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *1-366*  
    **hour** : int, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Hour  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *0-24*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *12*  
    **minute** : int, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Minutes  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *0-60*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *0*  
    **second** : int, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Seconds  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *0-60*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *0*  
    **flags** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *t*, *s*  
    &nbsp;&nbsp;&nbsp;&nbsp;**t**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Time is local sidereal time, not Greenwich standard time  
    &nbsp;&nbsp;&nbsp;&nbsp;**s**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Do not use SOLPOS algorithm of NREL  
    **overwrite** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Allow output files to overwrite existing files  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **verbose** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Verbose module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **quiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **superquiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Very quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  

    Returns:

    **result** : grass.tools.support.ToolResult | np.ndarray | tuple[np.ndarray] | None  
    If the tool produces text as standard output, a *ToolResult* object will be returned. Otherwise, `None` will be returned. If an array type (e.g., *np.ndarray*) is used for one of the raster outputs, the result will be an array and will have the shape corresponding to the computational region. If an array type is used for more than one raster output, the result will be a tuple of arrays.

    Raises:

    *grass.tools.ToolError*: When the tool ended with an error.

=== "Python (grass.script)"

    **elevation** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Output raster map with solar elevation angle  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output raster map  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, raster, *name*  
    **azimuth** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Output raster map with solar azimuth angle  
    &nbsp;&nbsp;&nbsp;&nbsp;Name for output raster map  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, raster, *name*  
    **sunhour** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Output raster map with sunshine hours  
    &nbsp;&nbsp;&nbsp;&nbsp;Sunshine hours require SOLPOS use and Greenwich standard time  
    &nbsp;&nbsp;&nbsp;&nbsp;Used as: output, raster, *name*  
    **year** : int, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Year  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *1950-2050*  
    **month** : int, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Month  
    &nbsp;&nbsp;&nbsp;&nbsp;If not given, day is interpreted as day of the year  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *1-12*  
    **day** : int, *required*  
    &nbsp;&nbsp;&nbsp;&nbsp;Day  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *1-366*  
    **hour** : int, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Hour  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *0-24*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *12*  
    **minute** : int, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Minutes  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *0-60*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *0*  
    **second** : int, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Seconds  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *0-60*  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *0*  
    **flags** : str, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Allowed values: *t*, *s*  
    &nbsp;&nbsp;&nbsp;&nbsp;**t**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Time is local sidereal time, not Greenwich standard time  
    &nbsp;&nbsp;&nbsp;&nbsp;**s**  
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Do not use SOLPOS algorithm of NREL  
    **overwrite** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Allow output files to overwrite existing files  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **verbose** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Verbose module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **quiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*  
    **superquiet** : bool, *optional*  
    &nbsp;&nbsp;&nbsp;&nbsp;Very quiet module output  
    &nbsp;&nbsp;&nbsp;&nbsp;Default: *None*

## DESCRIPTION

*r.sunhours* calculates sun elevation and sun azimuth angles for the
given time of day and each grid cell in the current region.
Additionally, the photoperiod (sunshine hours on flat terrain) can be
calculated.

Sun elevation, height, height angle, or solar altitude angle is the
angle in degrees between the horizon and a line that points from the
site towards the centre of the sun.

The sun azimuth angle is here defined as the azimuth angle in degrees of
the sun from due north in a clockwise direction.

The time used here is defined such that 12:00 (high noon) is the time
when the sun has reached its highest point in the sky at the current
site, unless the *-t* flag is used in which case time is interpreted as
Greenwich standard time.

If a *sunhour* output map is specified, the module calculates sunshine
hours for the given day. This option requires both Greenwhich standard
time and the use of the SOLPOS algorithm by NREL.

## NOTES

To consider also cast shadow effects of the terrain, *r.sun* has to be
used.

## EXAMPLES

### Calculating a sun elevation angle map

Calculate the sun elevation angle map for 2010-10-11 at 14:00h solar
time:

```sh
# set computational region to North Carolina state extent
g.region n=318500 s=-16000 w=124000 e=963000 res=500 -p
r.sunhours elevation=sun_elev year=2010 month=10 day=11 hour=14 minute=00

# visualize
d.mon wx0
d.rast sun_elev
d.vect nc_state type=boundary
d.legend sun_elev -s
```

![Sun angle map (in degree) of NC, USA](r_sunhours.png)  
*Sun angle map (in degree) of North Carolina for the 2010-10-11 at
14:00h solar time*

### Calculate map of photoperiod (insolation time)

Calculate photoperiod of day-of-year 001 (1st January) of 2012 for the
current computational region, ignoring cast shadow effects of the
terrain:

```sh
g.region -p
r.sunhours sunhour=photoperiod_doy_001 year=2012 day=1
```

## Acknowledgements

Acknowledgements: National Renewable Energy Laboratory for their [SOLPOS
2.0](http://rredc.nrel.gov/solar/codesandalgorithms/solpos/) sun
position algorithm.

## SEE ALSO

*[g.region](g.region.md), [r.sun](r.sun.md), [r.sunmask](r.sunmask.md)*

## AUTHOR

Markus Metz

## SOURCE CODE

Available at: [r.sunhours source code](https://github.com/OSGeo/grass/tree/main/raster/r.sunhours)
([history](https://github.com/OSGeo/grass/commits/main/raster/r.sunhours))  
Accessed: Saturday May 09 12:59:38 2026
