For general use, I recommend the sunrise.set() function in package StreamMetabolism. It takes parameters as latitude, longitude, starting date, and number of days desired.
StreamMetabolism::sunrise.set(lat=lat, long=lon,
date=SD, num.days=nDays)The trick is that the date parameter must be a character value of the form “YYYY/mm/dd”. See the example below for code converting from beginning an ending dates to SD and nDays. For specific uses, other packages may be easier or better.
Animals don’t have Mickey Mouse watches on their hooves or pennae that they consult to schedule their daily activities. Photosynthesis isn’t a 9-5 job for most plants. Rather, sunrise and sunset times tend to matter more in ecology than clock times. And, the clock times of sunrise and sunset vary by location and date, so they need to be calculated. The two obvious use cases for NPS natural resource Inventory & Monitoring are timestamped location data from GPS tags, or daytime/night for instrumentation data or low tide events.
The good news is that because so many different fields need such ephemeris data, other folks have done the heavy lifting (and testing) for us: multiple packages already have functions for calculating them. The bad news is that it isn’t obvious which package to use, or exactly what values each provides. This document a quick & dirty overview of some packages. It was initially meant to generate html for my NPS Google Site, but it turns out that html from knitr & pandoc isn’t handled cleanly in Google Sites, so I have a stripped version there and am putting the more complete version here for anyone to see or comment on.
The first task is determining which version or definition of sunrise & sunset you want: civil, nautical, astronomical. That’s an ecological question, so outside the scope of these pages on R. In rough terms, sunset is not when the center of the sun crosses the true horizon, nor when the last top edge of the sun crosses the true horizon. Because of light refraction, what we perceive as sunset is roughly 5 or 6 minutes after the sun goes below the true horizon, which is often the definition of “sunset” if no modifiers are specified. Different packages make different definitions available, often in different functions accepting parameters in different forms, and providing results in different forms.
The second issue is how exact of an answer you need, given that none of the definitions are defined by specific light levels. RAtmosphere simply calculates times for 1:365 day of year (DoY) for a given location, which means that estimates near the Equinox can be off by a couple of minutes from leap years among other issues. Unless you’re predicting a 10 second interval for a potential green flash, perhaps a minute or two difference (the same across days) is good enough. These calculations are also for unobstructed horizons. If your location of interest is on the side of a mountain or at the bottom of a canyon, these calculations will still correlate with the brightness of the sky, but if you need direct sunlight, you will need to calculate horizon elevations around each point of interest, then use one of the more complex packages that compute solar azimuth & elevation for a given location and date time.
Here’s a summary table of the packages and functions tested below.
| Package Name | Function | Use Notes |
|---|---|---|
| maptools | sunriset() | input location as coordinates matrix or sp object, dates as POSIXct output is dataframe of ToD in fractional hours and POSIXct |
| StreamMetabolism | sunrise.set() | input is lat, long, start date as character “YYYY.mm.dd” plus number of days output is data frame of POSIXct sunrise & sunset |
| RAtmosphere | suncalc | input is DoY integer (can be vector), Lat, Lon output is named list of 2: sunrise and sunset |
| HelpersMG | sun.info() | input is Dates as Dates object, latitude, longitude output is dataframe of sunrise, sunset, daylength, in decimal hours and POSIXct |
| RchivalTag | get_DayTimeLimits() | input is dataframe of date.long dates as POSIXct, Lon, Lat output is that dataframe plus sunrise sunset nautical & astronomical dawn & dusk in POSIXct |
| suncalc | getSunlightTimes() | uses external suncalc.js library user can choose which definitions are desired. package also has functions for phases of the moon, moon positions, etc. |
| Not tested: | ||
| GeoLight | twilight() | iterative refinements; package meant for deriving locations of tagged birds from light levels, so supports defining specific light levels |
| LakeMetabolizer | sun.rise.set() | uses latitude but not longitude |
| photobiology | sunrise(), sunset() sunrise_time() sunset_time() day_night() | sunrise_time() & sunset_time() allow specification of either named twilight (“civil”) or angle of occlusion in degrees, which could be useful for mountains or occluded horizons. |
| PWFSLSmoke | timeInfo() | package for AQ data |
| openair | cutData() | appears to allow splitting data by times relative to sunrise/sunset |
| fishmethods | astrocalc4r() | specify date as separate day, month, year, timezone parameters; can get solar angles, too. |
These are not the only packages that compute ephemeris data. If you need something else, either use your best google-fu, use R site search or Rseek, or search in page (ctrl-f) the list of CRAN packages by name: https://cran.r-project.org/web/packages/available_packages_by_name.html
The first test data are from my use case: sunrise and sunset to combine with the 6 minute tidal predictions for the Rocky Intertidal at CABR from Jan 1 2016 through Dec 31 2030, so 15 years. I include the conversion steps to get my generic test data into the format desired, then the call to the function, then wrap that in system.time() to illustrate how long each approach takes. [Spoiler alert: none take more than 10-15 seconds for 15 years, so differences among packages in your coding and verification time are much larger than differences in running time.]
Then, I use each approach to estimate sunrise and sunset on the Vernal (spring) Equinox. For the San Diego location used, sunrise should be about 6:53am local time and sunset 6:59pm (18:59). For those returning values in POSIXct, I also call tz() to show which timezone (if any) is specified for the results.
# Test Case
# CABR tidepools (see page on 6 minute tides)
lat <- 32.669494
lon <- -117.245418
# maptools::sunriset wants location as sp object or matrix of x,y
Location <- matrix(c(lon,lat), nrow=1)
myTZ <- "America/Los_Angeles" # use Sys.timezone() to get correct name for your computer's timezone
# numerical offsets don't work here, as "America/Los Angeles" specifies DST behavior since
# DST was started (so lots of different TZ definitions in Ohio!)
StartDate <- as.Date("2016-01-01")
EndDate <- as.Date("2030-12-31")
Dates <- seq(from=StartDate,to=EndDate,by="day") # object of class Date
# Equinox to simplify distinguishing which sunset is given
Equinox <- as.Date("2018-03-21")
pEquinox <- as.POSIXct(format(Equinox),tz=myTZ)# StreamMetabolism
system.time( {
# StreamMetabolism::sunrise.set wants start date as char and number of days
SD <- format(StartDate,format="%Y/%m/%d/")
nDays <- EndDate - StartDate + 1
riseset <- StreamMetabolism::sunrise.set(lat=lat, long=lon,
date=SD, num.days=nDays)
} )
str(riseset)
tz(riseset$sunrise)
head(riseset)
cat("In local Time\n")
with_tz(riseset[1:4,],tzone=myTZ)
cat("Equinox\n")
with_tz(StreamMetabolism::sunrise.set(lat=lat, long=lon,
date=Equinox, num.days=1),tzone=myTZ) user system elapsed
0.75 0.01 0.78
'data.frame': 5479 obs. of 2 variables:
$ sunrise: POSIXct, format: "2016-01-01 14:51:06" "2016-01-02 14:51:18" ...
$ sunset : POSIXct, format: "2016-01-02 00:53:54" "2016-01-03 00:54:38" ...
[1] "UTC"
| sunrise | sunset |
|---|---|
| 2016-01-01 14:51:06 | 2016-01-02 00:53:54 |
| 2016-01-02 14:51:18 | 2016-01-03 00:54:38 |
| 2016-01-03 14:51:29 | 2016-01-04 00:55:24 |
| 2016-01-04 14:51:38 | 2016-01-05 00:56:10 |
| 2016-01-05 14:51:45 | 2016-01-06 00:56:57 |
| 2016-01-06 14:51:51 | 2016-01-07 00:57:46 |
In local Time
| sunrise | sunset |
|---|---|
| 2016-01-01 06:51:06 | 2016-01-01 16:53:54 |
| 2016-01-02 06:51:18 | 2016-01-02 16:54:38 |
| 2016-01-03 06:51:29 | 2016-01-03 16:55:24 |
| 2016-01-04 06:51:38 | 2016-01-04 16:56:10 |
Equinox
| sunrise | sunset | |
|---|---|---|
| newlon | 2018-03-20 06:52:33 | 2018-03-20 19:00:38 |
Unless I need additional definitions, this is the function I use. The slight annoyance of converting StartDate to a character string merely requires one call to format.Date(). The output dataframe is in the best format for cutpoints for day lengths, day / night or other time of day bins, and most uses: POSIXct with tzone=“UTC”. When working with dates and times, always keep all your different inputs in UTC/GMT and only display your output in local time. I might need to create a Date variable to match-merge with other data.
# suncalc documentation doesn't show that d can be vector of days
DoY <- 1:365
system.time(SC <- RAtmosphere::suncalc(DoY,Lat=lat,Long=lon))
str(SC)
SC <- as.data.frame(SC) # convert from list to dataframe
head(SC)
cat("Equinox\n")
RAtmosphere::suncalc(79,Lat=lat,Long=lon) user system elapsed
0 0 0
List of 2
$ sunrise: num [1:365] 7.04 7.04 7.04 7.04 7.04 ...
$ sunset : num [1:365] 17.1 17.1 17.1 17.1 17.2 ...
| sunrise | sunset |
|---|---|
| 7.035198 | 17.10641 |
| 7.037811 | 17.11875 |
| 7.039976 | 17.13137 |
| 7.041690 | 17.14424 |
| 7.042951 | 17.15737 |
| 7.043758 | 17.17073 |
Equinox
$sunrise
[1] 6.069714
$sunset
[1] 18.20246
So the result is a list of 2 vectors sunrise and sunset, in time of day as decimal hours. These require a bit of munging to glue onto other data via DoY, and a cludge for DoY=366 in leap years (treat as same values as 365). Also, the definitions used for sunrise and sunset are not the horizon + refraction times, nor do they align with what other functions give for civil dawn & dusk. This is not a criticism of the RAtmosphere package: it is designed for other domains, and ephemeris calculations are a small convenience component. The values it gives may be the most appropriate for those other purposes.
# HelpersMG
system.time(MG <- sun.info(Dates,latitude=lat,longitude=lon))
str(MG)
tz(MG$date.time.sunrise)
tz(MG$date.time.sunrise.UTC)
head(MG)
cat("Equinox\n")
sun.info(Equinox,latitude=lat,longitude=lon) user system elapsed
0.52 0.00 0.55
'data.frame': 5479 obs. of 9 variables:
$ sunrise : num 7.85 7.85 7.86 7.86 7.86 ...
$ sunset : num 17.9 17.9 17.9 18 18 ...
$ day.length : num 10.1 10.1 10.1 10.1 10.1 ...
$ date.time.sunrise : POSIXct, format: "2016-01-01 07:51:05" "2016-01-02 07:51:15" ...
$ date.time.sunset : POSIXct, format: "2016-01-01 17:55:21" "2016-01-02 17:56:06" ...
$ date.time.sunrise.UTC: POSIXct, format: "2016-01-01 07:51:05" "2016-01-02 07:51:15" ...
$ date.time.sunset.UTC : POSIXct, format: "2016-01-01 17:55:21" "2016-01-02 17:56:06" ...
$ time.sunrise.UTC : num 7.85 7.85 7.86 7.86 7.86 ...
$ time.sunset.UTC : num 17.9 17.9 17.9 18 18 ...
[1] "Etc/GMT-4"
[1] "UTC"
| sunrise | sunset | day.length | date.time.sunrise | date.time.sunset | date.time.sunrise.UTC | date.time.sunset.UTC | time.sunrise.UTC | time.sunset.UTC |
|---|---|---|---|---|---|---|---|---|
| 7.851559 | 17.92277 | 10.07121 | 2016-01-01 07:51:05 | 2016-01-01 17:55:21 | 2016-01-01 07:51:05 | 2016-01-01 17:55:21 | 7.851389 | 17.92250 |
| 7.854172 | 17.93511 | 10.08094 | 2016-01-02 07:51:15 | 2016-01-02 17:56:06 | 2016-01-02 07:51:15 | 2016-01-02 17:56:06 | 7.854167 | 17.93500 |
| 7.856337 | 17.94773 | 10.09139 | 2016-01-03 07:51:22 | 2016-01-03 17:56:51 | 2016-01-03 07:51:22 | 2016-01-03 17:56:51 | 7.856111 | 17.94750 |
| 7.858051 | 17.96060 | 10.10255 | 2016-01-04 07:51:28 | 2016-01-04 17:57:38 | 2016-01-04 07:51:28 | 2016-01-04 17:57:38 | 7.857778 | 17.96056 |
| 7.859312 | 17.97373 | 10.11441 | 2016-01-05 07:51:33 | 2016-01-05 17:58:25 | 2016-01-05 07:51:33 | 2016-01-05 17:58:25 | 7.859167 | 17.97361 |
| 7.860119 | 17.98709 | 10.12697 | 2016-01-06 07:51:36 | 2016-01-06 17:59:13 | 2016-01-06 07:51:36 | 2016-01-06 17:59:13 | 7.860000 | 17.98694 |
Equinox
| sunrise | sunset | day.length | date.time.sunrise | date.time.sunset | date.time.sunrise.UTC | date.time.sunset.UTC | time.sunrise.UTC | time.sunset.UTC |
|---|---|---|---|---|---|---|---|---|
| 6.864038 | 19.03032 | 12.16628 | 2018-03-21 06:51:50 | 2018-03-21 19:01:49 | 2018-03-21 06:51:50 | 2018-03-21 19:01:49 | 6.863889 | 19.03028 |
The result is a dataframe with sunrise and sunset in multiple formats: time of day (fractional hours), POSIXct with tzone set to either a non-standard “Etc/GMT-4” or “UTC” for the *.UTC variables (the timezone of those coordinates and my computer is GMT-7 or GMT-8, so I don’t know what Etc/GTM-4 is about). Note that on display, the UTC POSIXct values are printed as local.time on my computer. If you use this function, use the .UTC versions of the results.
maptools has many functions useful for dealing with maps and spatial data, such as finding the nearest point on a line. It also has a set of sun-methods functions for crepuscule, sunrise/sunset, solar positions, etc.
# maptools
system.time( {
# maptools::sunriset wants dates as POSIX
# slightly more of a PitB than it should be, because as.POSIXct.Date doesn't use a tz
pDates <- as.POSIXct(format(Dates),tz=myTZ)
MTrise <- sunriset(Location, pDates,
direction="sunrise", POSIXct.out=TRUE)
MTset <- sunriset(Location, pDates,
proj4string=CRS("+proj=longlat +datum=WGS84"),
direction="sunset", POSIXct.out=TRUE)
MT <- data.frame(Date=pDates,
Sunrise=MTrise$time,
Sunset=MTset$time)
} )
str(MTrise)
tz(MTrise)
head(MT)
cat("Equinox\n")
sunriset(Location, pEquinox,
direction="sunrise", POSIXct.out=TRUE)
sunriset(Location, pEquinox,
direction="sunset", POSIXct.out=TRUE) user system elapsed
1.23 0.02 1.32
'data.frame': 5479 obs. of 2 variables:
$ day_frac: num 0.285 0.286 0.286 0.286 0.286 ...
$ time : POSIXct, format: "2016-01-01 06:51:06" "2016-01-02 06:51:18" ...
[1] "UTC"
| Date | Sunrise | Sunset |
|---|---|---|
| 2016-01-01 | 2016-01-01 06:51:06 | 2016-01-01 16:53:54 |
| 2016-01-02 | 2016-01-02 06:51:18 | 2016-01-02 16:54:38 |
| 2016-01-03 | 2016-01-03 06:51:29 | 2016-01-03 16:55:24 |
| 2016-01-04 | 2016-01-04 06:51:38 | 2016-01-04 16:56:10 |
| 2016-01-05 | 2016-01-05 06:51:45 | 2016-01-05 16:56:57 |
| 2016-01-06 | 2016-01-06 06:51:51 | 2016-01-06 16:57:46 |
Equinox
| day_frac | time | |
|---|---|---|
| newlon | 0.2855875 | 2018-03-21 06:51:14 |
| day_frac | time | |
|---|---|---|
| newlon | 0.7926059 | 2018-03-21 19:01:21 |
The results are both fraction of day and POSIXct, but separate for sunrise & sunset. My code combining the results into a dataframe could include the day_frac variables if desired.
This function wants parameters as a dataframe with date.long as POSIXct, Lon as longitude, and Lat with latitude.
# RchivalTag::get_DayTimeLimits wants a dataframe it will return with additional columns
system.time({
pDates <- as.POSIXct(format(Dates),tz=myTZ) # same as above
RTdf <- data.frame(date.long=pDates,
Lon=rep(lon,nDays),
Lat=rep(lat,nDays)
)
RT <- get_DayTimeLimits(RTdf)
} )
str(RT)
tz(RT$sunrise)
head(RT)
cat("Equinox\n")
RTdf2 <- data.frame(date.long=pEquinox,
Lon=lon,
Lat=lat
)
get_DayTimeLimits(RTdf2) user system elapsed
3.44 0.04 3.61
'data.frame': 5479 obs. of 9 variables:
$ date.long: POSIXct, format: "2016-01-01" "2016-01-02" ...
$ Lon : num -117 -117 -117 -117 -117 ...
$ Lat : num 32.7 32.7 32.7 32.7 32.7 ...
$ sunrise : POSIXct, format: "2016-01-01 06:51:06" "2016-01-02 06:51:18" ...
$ sunset : POSIXct, format: "2016-01-01 16:53:54" "2016-01-02 16:54:38" ...
$ dawn.naut: POSIXct, format: "2016-01-01 05:53:16" "2016-01-02 05:53:31" ...
$ dawn.ast : POSIXct, format: "2016-01-01 05:23:17" "2016-01-02 05:23:33" ...
$ dusk.naut: POSIXct, format: "2016-01-01 17:51:43" "2016-01-02 17:52:25" ...
$ dusk.ast : POSIXct, format: "2016-01-01 18:21:42" "2016-01-02 18:22:22" ...
[1] "America/Los_Angeles"
| date.long | Lon | Lat | sunrise | sunset | dawn.naut | dawn.ast | dusk.naut | dusk.ast |
|---|---|---|---|---|---|---|---|---|
| 2016-01-01 | -117.2454 | 32.66949 | 2016-01-01 06:51:06 | 2016-01-01 16:53:54 | 2016-01-01 05:53:16 | 2016-01-01 05:23:17 | 2016-01-01 17:51:43 | 2016-01-01 18:21:42 |
| 2016-01-02 | -117.2454 | 32.66949 | 2016-01-02 06:51:18 | 2016-01-02 16:54:38 | 2016-01-02 05:53:31 | 2016-01-02 05:23:33 | 2016-01-02 17:52:25 | 2016-01-02 18:22:22 |
| 2016-01-03 | -117.2454 | 32.66949 | 2016-01-03 06:51:29 | 2016-01-03 16:55:24 | 2016-01-03 05:53:44 | 2016-01-03 05:23:47 | 2016-01-03 17:53:07 | 2016-01-03 18:23:04 |
| 2016-01-04 | -117.2454 | 32.66949 | 2016-01-04 06:51:38 | 2016-01-04 16:56:10 | 2016-01-04 05:53:56 | 2016-01-04 05:24:01 | 2016-01-04 17:53:50 | 2016-01-04 18:23:46 |
| 2016-01-05 | -117.2454 | 32.66949 | 2016-01-05 06:51:45 | 2016-01-05 16:56:57 | 2016-01-05 05:54:07 | 2016-01-05 05:24:12 | 2016-01-05 17:54:34 | 2016-01-05 18:24:28 |
| 2016-01-06 | -117.2454 | 32.66949 | 2016-01-06 06:51:51 | 2016-01-06 16:57:46 | 2016-01-06 05:54:16 | 2016-01-06 05:24:23 | 2016-01-06 17:55:19 | 2016-01-06 18:25:12 |
Equinox
| date.long | Lon | Lat | sunrise | sunset | dawn.naut | dawn.ast | dusk.naut | dusk.ast |
|---|---|---|---|---|---|---|---|---|
| 2018-03-21 | -117.2454 | 32.66949 | 2018-03-21 06:51:14 | 2018-03-21 19:01:21 | 2018-03-21 05:57:58 | 2018-03-21 05:28:59 | 2018-03-21 19:54:38 | 2018-03-21 20:23:39 |
The result is a dataframe with sunrise/sunset, but also astronomical & nautical versions of both twilights. I do not know whether it is picking up the timezone from my computer’s timezone Sys.timezone() or the latitude longitude location; I suspect the former, which could be wrong for networks with sites in different timezones. If you use this function, please check your work for timezone issues!
The above function only compute sunrise & sunset based on level land to the horizon. If your locations are on the sides of mountains or in valleys, those times still indicate something about brightness of the sky, but they do not reflect when the sun will come up over the mountain or wall of the canyon. If you need times of direct sunlight over obstructed horizons, you will need to compute angular elevation of the horizon for most East & West angles, then use a full astronomical ephemeris function to compute sun positions in terms of direction and elevation relative to your point of interest.
StreamMetabolism::sunrise.set(lat=lat, long=lon,
date=SD, num.days=nDays)
pkgList <- c("knitr",
"plyr", "lubridate", # data and dates & times manipulation
"spam", # sparse matrices, not the Hawai'ian delicacy!
"maptools", # sunriset
"StreamMetabolism", # sunrise.set
"HelpersMG", # sun.info
"RAtmosphere", # suncalc
"RchivalTag", # get_DayTimeLimits
"GeoLight", # twilight
"ggplot2") # in case I add graphs to this page
inst <- pkgList %in% installed.packages()
if (length(pkgList[!inst]) > 0) install.packages(pkgList[!inst])
lapply(pkgList, library, character.only = TRUE)
knitr::opts_chunk$set(fig.path = 'figures/',
comment="",
results='hold',
warning=FALSE, message=FALSE) # hide messages
# Test Case
# CABR tidepools (see page on 6 minute tides)
lat <- 32.669494
lon <- -117.245418
# maptools::sunriset wants location as sp object or matrix of x,y
Location <- matrix(c(lon,lat), nrow=1)
myTZ <- "America/Los_Angeles" # use Sys.timezone() to get correct name for your computer's timezone
# numerical offsets don't work here, as "America/Los Angeles" specifies DST behavior since
# DST was started (so lots of different TZ definitions in Ohio!)
StartDate <- as.Date("2016-01-01")
EndDate <- as.Date("2030-12-31")
Dates <- seq(from=StartDate,to=EndDate,by="day") # object of class Date
# Equinox to simplify distinguishing which sunset is given
Equinox <- as.Date("2018-03-21")
pEquinox <- as.POSIXct(format(Equinox),tz=myTZ)
# StreamMetabolism
system.time( {
# StreamMetabolism::sunrise.set wants start date as char and number of days
SD <- format(StartDate,format="%Y/%m/%d/")
nDays <- EndDate - StartDate + 1
riseset <- StreamMetabolism::sunrise.set(lat=lat, long=lon,
date=SD, num.days=nDays)
} )
str(riseset)
tz(riseset$sunrise)
head(riseset)
cat("In local Time\n")
with_tz(riseset[1:4,],tzone=myTZ)
cat("Equinox\n")
with_tz(StreamMetabolism::sunrise.set(lat=lat, long=lon,
date=Equinox, num.days=1),tzone=myTZ)
# suncalc documentation doesn't show that d can be vector of days
DoY <- 1:365
system.time(SC <- RAtmosphere::suncalc(DoY,Lat=lat,Long=lon))
str(SC)
SC <- as.data.frame(SC) # convert from list to dataframe
head(SC)
cat("Equinox\n")
RAtmosphere::suncalc(79,Lat=lat,Long=lon)
# HelpersMG
system.time(MG <- sun.info(Dates,latitude=lat,longitude=lon))
str(MG)
tz(MG$date.time.sunrise)
tz(MG$date.time.sunrise.UTC)
head(MG)
cat("Equinox\n")
sun.info(Equinox,latitude=lat,longitude=lon)
# maptools
system.time( {
# maptools::sunriset wants dates as POSIX
# slightly more of a PitB than it should be, because as.POSIXct.Date doesn't use a tz
pDates <- as.POSIXct(format(Dates),tz=myTZ)
MTrise <- sunriset(Location, pDates,
direction="sunrise", POSIXct.out=TRUE)
MTset <- sunriset(Location, pDates,
proj4string=CRS("+proj=longlat +datum=WGS84"),
direction="sunset", POSIXct.out=TRUE)
MT <- data.frame(Date=pDates,
Sunrise=MTrise$time,
Sunset=MTset$time)
} )
str(MTrise)
tz(MTrise)
head(MT)
cat("Equinox\n")
sunriset(Location, pEquinox,
direction="sunrise", POSIXct.out=TRUE)
sunriset(Location, pEquinox,
direction="sunset", POSIXct.out=TRUE)
# RchivalTag::get_DayTimeLimits wants a dataframe it will return with additional columns
system.time({
pDates <- as.POSIXct(format(Dates),tz=myTZ) # same as above
RTdf <- data.frame(date.long=pDates,
Lon=rep(lon,nDays),
Lat=rep(lat,nDays)
)
RT <- get_DayTimeLimits(RTdf)
} )
str(RT)
tz(RT$sunrise)
head(RT)
cat("Equinox\n")
RTdf2 <- data.frame(date.long=pEquinox,
Lon=lon,
Lat=lat
)
get_DayTimeLimits(RTdf2)