overview.knit

## Overview

The `solartime` package provides utilities to work with solar time, i.e. where noon is exactly when sun culminates. It provides functions to compute

- difference between local time zone and solar time
- sun position
- sunrise, sunset, daylength, and daytime flags

## Usage

    require(solartime)

    ## Loading required package: solartime

### Difference between solar time and local time

The city of Jena is located west of the timezone’s meridian. Hence, the sun culminates around 13 minutes later.

    latDeg <- 50.93; longDeg <- 11.57
    (localDiff <- computeSolarToLocalTimeDifference(longDeg, 1L)*60)

    ## [1] -13.72

The time difference shifts during the year because of earth orbit’s eccentricity.

    doy <- 1:366
    locaDiffDoi <- computeSolarToLocalTimeDifference(longDeg, 1L, doy)*60
    plot(locaDiffDoi  ~ doy, ylab = "time difference solar - local time (min)")
    abline(h = localDiff); abline(h = 0, lty = "dotted")

During most days, the sun culminates after noon, but during a few days in autumn the sun culminates earlier than noon of the local time zone.

### Computing sun position

Using function `computeSunPosition`.

    times <- seq(
      ISOdate(2018, 11, 21, 0, tz = "Etc/GMT-1"), by = "2 hour", length.out = 13)
    ans <- computeSunPosition(times, latDeg = latDeg, longDeg = longDeg)
    cbind(data.frame(timestamp = times), as.data.frame(ans))

    ##              timestamp         hour declination   elevation     azimuth
    ## 1  2018-11-21 00:00:00  0.007677319  -0.3428584 -1.02475619 0.003645122
    ## 2  2018-11-21 02:00:00  2.007677319  -0.3428584 -0.88587017 0.843474263
    ## 3  2018-11-21 04:00:00  4.007677319  -0.3428584 -0.59048251 1.386239933
    ## 4  2018-11-21 06:00:00  6.007677319  -0.3428584 -0.26282498 1.793575561
    ## 5  2018-11-21 08:00:00  8.007677319  -0.3428584  0.03683142 2.188474356
    ## 6  2018-11-21 10:00:00 10.007677319  -0.3428584  0.25645552 2.635087174
    ## 7  2018-11-21 12:00:00 12.007677319  -0.3428584  0.33904050 3.143599850
    ## 8  2018-11-21 14:00:00 14.007677319  -0.3428584  0.25522232 3.651797949
    ## 9  2018-11-21 16:00:00 16.007677319  -0.3428584  0.03476366 4.097884290
    ## 10 2018-11-21 18:00:00 18.007677319  -0.3428584 -0.26529678 4.492580298
    ## 11 2018-11-21 20:00:00 20.007677319  -0.3428584 -0.59297225 4.900381623
    ## 12 2018-11-21 22:00:00 22.007677319  -0.3428584 -0.88775827 5.444904168
    ## 13 2018-11-22 00:00:00  0.003498418  -0.3467846 -1.02868424 0.001669479

The return value is a data.frame with polar coordinates of the sun in radian on the horizontal coordinatesystem:

- elevation: angle above the horizon,
- azimuth: angle around the horizon, measured from true north increasing eastward, and
- declination: angle between celestial equator and the observers, fundamental plane, i.e. the plane that contains the horizon
- fractional hour after midnight

In the example the azimuth increases from slightly more than zero at midnight to 2\(\pi\) at the following midnight. Elevation increases from negative values to 0 at sunset, maximum at noon declining to zero at sunset. Declination in early winter decreases to more negative values until it reaches the negative of the earth axial tilt on December solstice.

### Sunrise and sunset

Sunrise and sunset are computed in fractional hours after midnight. Neglecting the difference between solar time and local time introduces a bias. Daylength is not biased by neglecting solar time correction.

    today <- as.POSIXlt(ISOdate(2018,3,1,0, tz = "Etc/GMT-1"))
    (sunrise <- computeSunriseHour(today, latDeg = latDeg
                                   , isCorrectSolartime = FALSE))

    ## [1] 6.685696

    (sunrise <- computeSunriseHour(today, latDeg = latDeg, longDeg = 11.586))

    ## [1] 7.129989

    (sunset <- computeSunsetHour(today, latDeg = latDeg, longDeg = 11.586))

    ## [1] 17.7586

    (daylength <- computeDayLength(today, latDeg = latDeg))

    ## [1] 10.62861

Sunrise is set to 12 for polar nights and 0 for polar days. Similarly, sunset is set to 12 for polar nights and to 0 for polar days.

    doy <- 1:366
    sunrise <- computeSunriseHourDoy( doy, latDeg = +80, isCorrectSolartime = FALSE)
    sunset <- computeSunsetHourDoy( doy, latDeg = +80, isCorrectSolartime = FALSE)
    par(mfrow = c(1,2)); plot(sunrise ~ doy ); plot(sunset ~ doy )

### Further Utilities

Functions `computeIsDayByHour` and `computeIsDayByLocation` quickly classify daytime and nighttime records of a dataset.

    dateSeq <- seq(
      as.POSIXct("2017-03-20", tz = "Etc/GMT-1")
      , as.POSIXct("2017-03-21", tz = "Etc/GMT-1")
      , by = "30 min")
    isDay <- computeIsDayByLocation(dateSeq, latDeg = 50.93, longDeg = 11.59)

Function `getHoursAheadOfUTC` provides the integer timeZone argument of a timestamp, required by other functions of the package. Similarly, `getFractionalHours` provides fractional hours after midnight of a timestamp.

    #around daylight saving time step in Central European time
    t1 <- as.POSIXct("2018-10-28 01:30", tz = "Europe/Berlin")
    datesCET <- seq(t1, by = "30 min", length.out = 6)
    datesUTC <- as.POSIXct(datesCET, tz = "UTC")
    #
    hoursAheadOfUTC <- getHoursAheadOfUTC(datesCET)
    fracHours <- getFractionalHours(datesCET)
    #
    data.frame(datesUTC, datesCET, hoursAheadOfUTC, fracHours)

    ##              datesUTC            datesCET hoursAheadOfUTC fracHours
    ## 1 2018-10-27 23:30:00 2018-10-28 01:30:00               2       1.5
    ## 2 2018-10-28 00:00:00 2018-10-28 02:00:00               2       2.0
    ## 3 2018-10-28 00:30:00 2018-10-28 02:30:00               2       2.5
    ## 4 2018-10-28 01:00:00 2018-10-28 02:00:00               1       3.0
    ## 5 2018-10-28 01:30:00 2018-10-28 02:30:00               1       3.5
    ## 6 2018-10-28 02:00:00 2018-10-28 03:00:00               1       4.0