round_date: Round, floor and ceiling methods for date-time objects

Description Usage Arguments Details Rounding Up Date Objects See Also Examples

View source: R/round.r

Description

Rounding to the nearest unit or multiple of a unit are supported. All meaningfull specifications in English language are supported - secs, min, mins, 2 minutes, 3 years etc.

Rounding to fractional seconds is supported. Please note that rounding to fractions smaller than 1s can lead to large precision errors due to the floating point representation of the POSIXct objects. See examples.

round_date() takes a date-time object and rounds it to the nearest value of the specified time unit. For rounding date-times which is exactly halfway between two consecutive units, the convention is to round up. Note that this is in line with the behavior of R's base::round.POSIXt() function but does not follow the convention of the base base::round() function which "rounds to the even digit" per IEC 60559.

floor_date() takes a date-time object and rounds it down to the nearest boundary of the specified time unit.

ceiling_date() takes a date-time object and rounds it up to the nearest boundary of the specified time unit.

Usage

1
2
3
4
5
6
7
8
round_date(x, unit = "second",
  week_start = getOption("lubridate.week.start", 7))

floor_date(x, unit = "seconds",
  week_start = getOption("lubridate.week.start", 7))

ceiling_date(x, unit = "seconds", change_on_boundary = NULL,
  week_start = getOption("lubridate.week.start", 7))

Arguments

x

a vector of date-time objects

unit

a character string specifying a time unit or a multiple of a unit to be rounded to. Valid base units are second, minute, hour, day, week, month, bimonth, quarter, season, halfyear and year. Arbitrary unique English abbreviations as in the period() constructor are allowed. Rounding to multiple of units (except weeks) is supported.

week_start

when unit is weeks specify the reference day; 7 being Sunday.

change_on_boundary

If NULL (the default) don't change instants on the boundary (ceiling_date(ymd_hms('2000-01-01 00:00:00')) is 2000-01-01 00:00:00), but round up Date objects to the next boundary (ceiling_date(ymd("2000-01-01"), "month") is "2000-02-01"). When TRUE, instants on the boundary are rounded up to the next boundary. When FALSE, date-time on the boundary are never rounded up (this was the default for lubridate prior to v1.6.0. See section Rounding Up Date Objects below for more details.

Details

In lubridate, rounding of a date-time objects tries to preserve the class of the input object whenever possible. This is done by first rounding to an instant and then converting to the original class by usual R conventions.

Rounding Up Date Objects

By default rounding up Date objects follows 3 steps:

  1. Convert to an instant representing lower bound of the Date: 2000-01-01 –> 2000-01-01 00:00:00

  2. Round up to the next closest rounding unit boundary. For example, if the rounding unit is month then next closest boundary of 2000-01-01 is 2000-02-01 00:00:00.

    The motivation for this is that the "partial" 2000-01-01 is conceptually an interval (2000-01-01 00:00:002000-01-02 00:00:00) and the day hasn't started clocking yet at the exact boundary 00:00:00. Thus, it seems wrong to round up a day to its lower boundary.

    The behavior on the boundary can be changed by setting change_on_boundary to a non-NULL value.

  3. If rounding unit is smaller than a day, return the instant from step 2 (POSIXct), otherwise convert to and return a Date object.

See Also

base::round()

Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
## print fractional seconds
options(digits.secs=6)

x <- ymd_hms("2009-08-03 12:01:59.23")
round_date(x, ".5s")
round_date(x, "sec")
round_date(x, "second")
round_date(x, "minute")
round_date(x, "5 mins")
round_date(x, "hour")
round_date(x, "2 hours")
round_date(x, "day")
round_date(x, "week")
round_date(x, "month")
round_date(x, "bimonth")
round_date(x, "quarter") == round_date(x, "3 months")
round_date(x, "halfyear")
round_date(x, "year")

x <- ymd_hms("2009-08-03 12:01:59.23")
floor_date(x, ".1s")
floor_date(x, "second")
floor_date(x, "minute")
floor_date(x, "hour")
floor_date(x, "day")
floor_date(x, "week")
floor_date(x, "month")
floor_date(x, "bimonth")
floor_date(x, "quarter")
floor_date(x, "season")
floor_date(x, "halfyear")
floor_date(x, "year")

x <- ymd_hms("2009-08-03 12:01:59.23")
ceiling_date(x, ".1 sec") # imprecise representation at 0.1 sec !!!
ceiling_date(x, "second")
ceiling_date(x, "minute")
ceiling_date(x, "5 mins")
ceiling_date(x, "hour")
ceiling_date(x, "day")
ceiling_date(x, "week")
ceiling_date(x, "month")
ceiling_date(x, "bimonth") == ceiling_date(x, "2 months")
ceiling_date(x, "quarter")
ceiling_date(x, "season")
ceiling_date(x, "halfyear")
ceiling_date(x, "year")

## As of R 3.4.2 POSIXct printing of fractional numbers is wrong
as.POSIXct("2009-08-03 12:01:59.3") ## -> "2009-08-03 12:01:59.2 CEST"
ceiling_date(x, ".1 sec") ## -> "2009-08-03 12:01:59.2 CEST"

x <- ymd("2000-01-01")
ceiling_date(x, "month")
ceiling_date(x, "month", change_on_boundary = TRUE)

lubridate documentation built on Nov. 17, 2017, 6:56 a.m.