Uses incoming parameters to return a pair of POSIXct times in the proper order. The first returned time will be midnight of the desired starting date. The second returned time will represent the "end of the day" of the requested or calculated enddate boundary.

Note that the returned end date will be one unit prior to the start of the requested enddate unless ceilingEnd = TRUE in which case the entire enddate will be included up to the last unit.

The ceilingEnd argument addresses the ambiguity of a phrase like: "August 1-8". With ceilingEnd = FALSE (default) this pharse means "through the beginning of Aug 8". With ceilingEnd = TRUE it means "through the end of Aug 8".

So, to get 24 hours of data staring on Jan 01, 2019 you would specify:


> MazamaCoreUtils::dateRange(20190101, 20190102, timezone = "UTC")
[1] "2019-01-01 00:00:00 UTC" "2019-01-01 23:59:59 UTC"

or


> MazamaCoreUtils::dateRange(20190101, 20190101,
                             timezone = "UTC", ceilingEnd = TRUE)
[1] "2019-01-01 00:00:00 UTC" "2019-01-01 23:59:59 UTC"

The required timezone parameter must be one of those found in OlsonNames.

Dates can be anything that is understood by lubrdiate::parse_date_time() using the Ymd[HMS] orders. This includes:

  • "YYYYmmdd"

  • "YYYYmmddHHMMSS"

  • "YYYY-mm-dd"

  • "YYYY-mm-dd H"

  • "YYYY-mm-dd H:M"

  • "YYYY-mm-dd H:M:S"

dateRange(
  startdate = NULL,
  enddate = NULL,
  timezone = NULL,
  unit = "sec",
  ceilingStart = FALSE,
  ceilingEnd = FALSE,
  days = 7
)

Arguments

startdate

Desired start datetime (ISO 8601).

enddate

Desired end datetime (ISO 8601).

timezone

Olson timezone used to interpret dates (required).

unit

Units used to determine time at end-of-day.

ceilingStart

Logical instruction to apply ceiling_date to the startdate rather than floor_date

ceilingEnd

Logical instruction to apply ceiling_date to the enddate rather than floor_date

days

Number of days of data to include.

Value

A vector of two POSIXcts.

Default Arguments

In the case when either startdate or enddate is missing, it is created from the non-missing values plus/minus days. If both startdate and enddate are misssing, enddate is set to now (with the given timezone), and then startdate is calculated using enddate - days.

End-of-Day Units

The second of the returned POSIXcts will end one unit before the specified enddate. Acceptable units are "day", "hour", "min", "sec".

The aim is to quickly calculate full-day date ranges for time series whose values are binned at different units. Thus, if unit = "min", the returned value associated with enddate will always be at 23:59:00 in the requested time zone.

POSIXct inputs

When startdate or enddate are already POSIXct values, they are converted to the timezone specified by timezone without altering the physical instant in time the input represents. This is different from the behavior of parse_date_time (which powers this function), which will force POSIXct inputs into a new timezone, altering the physical moment of time the input represents.

Parameter precedence

It is possible to supply input paramters that are in conflict. For example:

dateRange("2019-01-01", "2019-01-08", days = 3, timezone = "UTC")

The startdate and enddate parameters would imply a 7-day range which is in conflict with days = 3. The following rules resolve conflicts of this nature:

  1. When startdate and enddate are both specified, the days parameter is ignored.

  2. When startdate is missing, ceilingStart is ignored and the first returned time will depend on the combination of enddate, days and ceilingEnd.

  3. When enddate is missing, ceilingEnd is ignored and the second returned time depends on ceilingStart and days.

Examples

library(MazamaCoreUtils)

dateRange("2019-01-08", timezone = "UTC")
#> [1] "2019-01-08 00:00:00 UTC" "2019-01-14 23:59:59 UTC"
dateRange("2019-01-08", unit = "min", timezone = "UTC")
#> [1] "2019-01-08 00:00:00 UTC" "2019-01-14 23:59:00 UTC"
dateRange("2019-01-08", unit = "hour", timezone = "UTC")
#> [1] "2019-01-08 00:00:00 UTC" "2019-01-14 23:00:00 UTC"
dateRange("2019-01-08", unit = "day", timezone = "UTC")
#> [1] "2019-01-08 UTC" "2019-01-15 UTC"
dateRange("2019-01-08", "2019-01-11", timezone = "UTC")
#> [1] "2019-01-08 00:00:00 UTC" "2019-01-10 23:59:59 UTC"
dateRange(enddate = 20190112, days = 3,
          unit = "day", timezone = "America/Los_Angeles")
#> [1] "2019-01-09 PST" "2019-01-12 PST"