--- output: rmarkdown::html_vignette: keep_md: true vignette: > %\VignetteEngine{knitr::rmarkdown_notangle} %\VignetteIndexEntry{overview} %\usepackage[UTF-8]{inputenc} --- ```{r, include = FALSE} # do not execute on CRAN: # https://stackoverflow.com/questions/28961431/computationally-heavy-r-vignettes #is_check <- ("CheckExEnv" %in% search()) || any(c("_R_CHECK_TIMINGS_", # "_R_CHECK_LICENSE_") %in% names(Sys.getenv())) #knitr::opts_chunk$set(eval = !is_check) ``` ```{r setup, include = FALSE} # knitr::opts_knit$set(root.dir = '..') knitr::opts_chunk$set( fig.align = "center" #, fig.width = 3.27, fig.height = 2.5, dev.args = list(pointsize = 10) #,cache = TRUE , fig.width = 4.3, fig.height = 3.2, dev.args = list(pointsize = 10) #, fig.width = 6.3, fig.height = 6.2, dev.args = list(pointsize = 10) # works with html but causes problems with latex #,out.extra = 'style = "display:block; margin: auto"' ) knitr::knit_hooks$set(spar = function(before, options, envir) { if (before) { par(las = 1 ) #also y axis labels horizontal par(mar = c(1.8,2.3,0,0) + 0.3 ) #margins par(tck = 0.02 ) #axe-tick length inside plots par(mgp = c(1.1,0.2,0) ) #positioning of axis title, axis labels, axis } }) ``` ## 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 ```{r} require(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. ```{r} latDeg <- 50.93; longDeg <- 11.57 (localDiff <- computeSolarToLocalTimeDifference(longDeg, 1L)*60) ``` The time difference shifts during the year because of [earth orbit's eccentricity](https://en.wikipedia.org/wiki/Orbital_eccentricity). ```{r eccentricityPlot} 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`. ```{r} 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)) ``` The return value is a data.frame with polar coordinates of the sun in radian on the [horizontal coordinatesystem](https://en.wikipedia.org/wiki/Horizontal_coordinate_system): - elevation: angle above the horizon, - azimuth: angle around the horizon, measured from true north increasing eastward, and - [declination](https://en.wikipedia.org/wiki/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. ```{r} today <- as.POSIXlt(ISOdate(2018,3,1,0, tz = "Etc/GMT-1")) (sunrise <- computeSunriseHour(today, latDeg = latDeg , isCorrectSolartime = FALSE)) (sunrise <- computeSunriseHour(today, latDeg = latDeg, longDeg = 11.586)) (sunset <- computeSunsetHour(today, latDeg = latDeg, longDeg = 11.586)) (daylength <- computeDayLength(today, latDeg = latDeg)) ``` 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. ```{r polarSunrise} 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. ```{r} 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) ``` ```{r isDayPlot,echo=FALSE} plot( isDay ~ dateSeq ) sunrise <- computeSunriseHour(dateSeq[1], latDeg = 50.93, longDeg = 11.59) sunset <- computeSunsetHour(dateSeq[1], latDeg = 50.93, longDeg = 11.59) abline( v = trunc(dateSeq[1], units = "days") + c(sunrise,sunset)*3600L ) ``` 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. ```{r} #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) ```