test_that("floor_date works as expected with POSIX units", { set.seed(11111) x <- ymd_hms(c("2020-01-03 00:01:03", "2020-02-04 00:01:03", "2020-03-05 00:00:00"), tz = "America/New_York") min <- min(x) b <- ymd_hms(c("2020-01-03 00:00:01", "2020-02-05 00:00:01")) expect_equal(floor_date(x, b), b[c(1, 1, 2)]) expect_equal(floor_date(x, sample(b)), b[c(1, 1, 2)]) expect_equal(floor_date(x, rev(b)), b[c(1, 1, 2)]) expect_equal(floor_date(b, x), with_tz(c(b[1], x[2]), "America/New_York")) expect_equal(floor_date(b, sample(x)), with_tz(c(b[1], x[2]), "America/New_York")) expect_equal(floor_date(rev(b), x), with_tz(rev(c(b[1], x[2])), "America/New_York")) expect_equal(floor_date(rev(x), b), rev(b[c(1, 1, 2)])) expect_equal(floor_date(x, b[[2]]), c(with_tz(c(min, min), "UTC"), b[[2]])) expect_equal(floor_date(ymd_hms("2030-01-01 00:03:00"), x), x[[3]]) expect_equal(floor_date(y <- ymd_hms("2010-01-01 00:03:00"), x), with_tz(y, "America/New_York")) expect_equal(floor_date(ymd_hms("2030-01-01 00:03:00"), b), b[2]) }) test_that("floor_date works as expected with Date units", { set.seed(11111) x <- ymd(c("2020-01-03", "2020-02-04", "2020-03-05")) min <- min(x) b <- ymd(c("2020-01-03", "2020-02-05")) expect_equal(floor_date(x, b), b[c(1, 1, 2)]) expect_equal(floor_date(x, sample(b)), b[c(1, 1, 2)]) expect_equal(floor_date(x, rev(b)), b[c(1, 1, 2)]) expect_equal(floor_date(b, x), c(b[1], x[2])) expect_equal(floor_date(b, sample(x)), c(b[1], x[2])) expect_equal(floor_date(rev(b), x), rev(c(b[1], x[2]))) expect_equal(floor_date(rev(x), b), rev(b[c(1, 1, 2)])) expect_equal(floor_date(x, b[[2]]), c(c(min, min), b[[2]])) expect_equal(floor_date(ymd("2030-01-01"), x), x[[3]]) expect_equal(floor_date(y <- ymd("2010-01-01"), x), y) expect_equal(floor_date(ymd("2030-01-01"), b), b[2]) }) test_that("ceiling_date works as expected with POSIX units", { set.seed(11111) x <- ymd_hms(c("2020-01-03 00:01:03", "2020-02-04 00:01:03", "2020-03-05 00:00:00"), tz = "America/New_York") na <- x na[[2]] <- NA max <- max(x) b <- ymd_hms(c("2020-01-03 00:00:01", "2020-02-05 00:00:01")) expect_equal(ceiling_date(x, b), c(b[c(2, 2)], max)) expect_equal(ceiling_date(na, b), c(b[2], NA, max)) expect_equal(ceiling_date(rev(x), b), rev(c(b[c(2, 2)], max))) expect_equal(ceiling_date(x, sample(b)), c(b[c(2, 2)], max)) expect_equal(ceiling_date(x, rev(b)), c(b[c(2, 2)], max)) expect_equal(ceiling_date(b, x), x[c(1, 3)]) expect_equal(ceiling_date(b, sample(x)), x[c(1, 3)]) expect_equal(ceiling_date(rev(b), x), rev(x[c(1, 3)])) expect_equal(ceiling_date(x, b[[2]]), c(b[c(2, 2)], max)) expect_equal(ceiling_date(y <- ymd_hms("2030-01-01 00:03:00"), x), with_tz(y, "America/New_York")) expect_equal(ceiling_date(y <- ymd_hms("2010-01-01 00:03:00"), x), x[[1]]) }) test_that("ceiling_date works as expected with Date units", { set.seed(11111) x <- ymd(c("2020-01-04", "2020-02-04", "2020-03-05")) na <- x na[[2]] <- NA max <- max(x) b <- ymd(c("2020-01-03", "2020-02-05")) expect_equal(ceiling_date(x, b), c(b[c(2, 2)], max)) expect_equal(ceiling_date(x, rep(b, 3)), c(b[c(2, 2)], max)) expect_equal(ceiling_date(na, b), c(b[2], NA, max)) expect_equal(ceiling_date(rev(x), b), rev(c(b[c(2, 2)], max))) expect_equal(ceiling_date(x, sample(b)), c(b[c(2, 2)], max)) expect_equal(ceiling_date(x, rev(b)), c(b[c(2, 2)], max)) expect_equal(ceiling_date(b, x), x[c(1, 3)]) expect_equal(ceiling_date(b, sample(rep(x, 8))), x[c(1, 3)]) expect_equal(ceiling_date(rev(b), x), rev(x[c(1, 3)])) expect_equal(ceiling_date(x, b[[2]]), c(b[c(2, 2)], max)) expect_equal(ceiling_date(y <- ymd("2030-01-01"), x), y) expect_equal(ceiling_date(y <- ymd("2010-01-01"), x), x[[1]]) }) test_that("round_date works as expected with Date units", { set.seed(11111) x <- ymd(c("2020-01-04", "2020-02-04", "2020-03-05")) na <- x na[[2]] <- NA max <- max(x) b <- ymd(c("2020-01-03", "2020-02-05")) expect_equal(round_date(x, b), b[c(1, 2, 2)]) expect_equal(round_date(na, b), c(b[1], NA, b[2])) expect_equal(round_date(rev(x), b), b[c(2, 2, 1)]) expect_equal(round_date(x, sample(b)), b[c(1, 2, 2)]) expect_equal(round_date(x, rev(b)), b[c(1, 2, 2)]) expect_equal(round_date(x, rep(b, 10)), b[c(1, 2, 2)]) expect_equal(round_date(b, x), x[c(1, 2)]) expect_equal(round_date(b, sample(x)), x[c(1, 2)]) expect_equal(round_date(rev(b), x), rev(x[c(1, 2)])) expect_equal(round_date(y <- ymd("2030-01-01"), x), x[3]) expect_equal(round_date(y <- ymd("2010-01-01"), x), x[1]) }) test_that("round_date works on POSIXlt objects", { x <- as.POSIXlt(ymd_hms(c("2012-11-01 23:41:00", "2012-11-01 00:44:10"), tz = "America/New_York")) expect_equal( round_date(x, "5 mins"), as.POSIXlt(ymd_hms(c("2012-11-01 23:40:00", "2012-11-01 00:45:00"), tz = "America/New_York")) ) }) test_that("round_date fails with invalid date-time units", { expect_error(round_date(now(), .POSIXct(double())), "Zero") expect_error(floor_date(now(), .POSIXct(double())), "Zero") expect_error(ceiling_date(now(), .POSIXct(double())), "Zero") expect_error(round_date(now(), .POSIXct(NA_real_)), "NAs") expect_error(floor_date(now(), .POSIXct(NA_real_)), "NAs") expect_error(ceiling_date(now(), .POSIXct(NA_real_)), "NAs") }) test_that("floor_date works for each time element", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") expect_identical(floor_date(x, "second"), as.POSIXct("2009-08-03 12:01:59", tz = "UTC")) expect_identical(floor_date(x, "minute"), as.POSIXct("2009-08-03 12:01:00", tz = "UTC")) expect_identical(floor_date(x, "hour"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_identical(floor_date(x, "day"), as.POSIXct("2009-08-03 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "week"), as.POSIXct("2009-08-02 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "month"), as.POSIXct("2009-08-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "bimonth"), as.POSIXct("2009-07-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "quarter"), as.POSIXct("2009-07-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "halfyear"), as.POSIXct("2009-07-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "year"), as.POSIXct("2009-01-01 00:00:00", tz = "UTC")) }) test_that("floor_date and round_date throw on invalid multi-unit spec", { x <- ymd_hms("2009-08-03 12:01:57.11") expect_error(floor_date(x, "120 sec")) expect_error(floor_date(x, "120 min")) expect_error(floor_date(x, "25 h")) expect_error(floor_date(x, "32 days")) }) test_that("floor_date works for multi-units", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") expect_identical(floor_date(x, "2 secs"), as.POSIXct("2009-08-03 12:01:58", tz = "UTC")) expect_identical(floor_date(x, "2s"), as.POSIXct("2009-08-03 12:01:58", tz = "UTC")) expect_identical(floor_date(x, "2 mins"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_identical(floor_date(x, "2M"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_identical(floor_date(x, "2 hours"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_identical(floor_date(x, "2h"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_identical(floor_date(x, "2 days"), as.POSIXct("2009-08-03 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "3 days"), as.POSIXct("2009-08-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "10 days"), as.POSIXct("2009-08-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "10d"), as.POSIXct("2009-08-01 00:00:00", tz = "UTC")) ## expect_identical(floor_date(x, "2 week"), as.POSIXct("2009-08-xx 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "2 month"), as.POSIXct("2009-07-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "2m"), as.POSIXct("2009-07-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "2 bimonth"), floor_date(x, "4 months")) expect_identical(floor_date(x, "2 quarter"), floor_date(x, "6 months")) expect_identical(floor_date(x, "2 halfyear"), floor_date(x, "year")) expect_identical(floor_date(x, "2 year"), as.POSIXct("2008-01-01 00:00:00", tz = "UTC")) }) test_that("floor_date works for fractional multi-units", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") expect_identical(floor_date(x, ".2 secs"), as.POSIXct("2009-08-03 12:01:59.2", tz = "UTC")) expect_identical(floor_date(x, ".1s"), as.POSIXct("2009-08-03 12:01:59.2", tz = "UTC")) expect_identical(floor_date(x, ".05s"), as.POSIXct("2009-08-03 12:01:59.2", tz = "UTC")) expect_identical(floor_date(x, ".01s"), as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC")) expect_identical(floor_date(x, ".005s"), as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC")) expect_identical(floor_date(x, ".5 mins"), as.POSIXct("2009-08-03 12:01:30", tz = "UTC")) }) test_that("multi-unit rounding works the same for POSIX and Date objects", { px <- ymd("2009-08-01", tz = "UTC") dt <- ymd("2009-08-01") expect_identical(floor_date(px, "5 mins"), floor_date(dt, "5 mins")) expect_identical(floor_date(px, "5 mins"), floor_date(dt, "5 mins")) expect_identical(ceiling_date(px + 0.0001, "5 mins"), ceiling_date(dt, "5 mins")) expect_identical( ceiling_date(px, "5 mins", change_on_boundary = T), ceiling_date(dt, "5 mins", change_on_boundary = T) ) expect_identical(ceiling_date(px + 0.001, "5 hours"), ceiling_date(dt, "5 hours")) expect_identical(ceiling_date(px + 0.0001, "5 hours", change_on_boundary = T), ceiling_date(dt, "5 hours", change_on_boundary = T)) expect_identical(ceiling_date(px + 0.001, "2 hours"), ceiling_date(dt, "2 hours")) expect_identical(as_date(floor_date(px, "2 days")), floor_date(dt, "2 days")) expect_identical(as_date(ceiling_date(px + 0.001, "2 days")), ceiling_date(dt, "2 days")) expect_identical(as_date(floor_date(px, "5 days")), floor_date(dt, "5 days")) expect_identical(as_date(ceiling_date(px + 0.001, "5 days")), ceiling_date(dt, "5 days")) expect_identical(as_date(floor_date(px, "2 months")), floor_date(dt, "2 months")) expect_identical(as_date(ceiling_date(px, "2 months")), ceiling_date(dt, "2 months")) expect_identical(as_date(floor_date(px, "5 months")), floor_date(dt, "5 months")) expect_identical(as_date(ceiling_date(px, "5 months")), ceiling_date(dt, "5 months")) }) test_that("ceiling_date works for multi-units", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") y <- as.POSIXct("2009-08-03 12:01:30.23", tz = "UTC") z <- as.POSIXct("2009-08-24 12:01:30.23", tz = "UTC") expect_identical(ceiling_date(x, "2 secs"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_identical(ceiling_date(x, "3 secs"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_identical(ceiling_date(x, "5 secs"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_identical(ceiling_date(y, "2 secs"), as.POSIXct("2009-08-03 12:01:32", tz = "UTC")) expect_identical(ceiling_date(y, "3 secs"), as.POSIXct("2009-08-03 12:01:33", tz = "UTC")) expect_identical(ceiling_date(y, "5 secs"), as.POSIXct("2009-08-03 12:01:35", tz = "UTC")) expect_identical(ceiling_date(x, "2 mins"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_identical(ceiling_date(x, "3 mins"), as.POSIXct("2009-08-03 12:03:00", tz = "UTC")) expect_identical(ceiling_date(x, "5 mins"), as.POSIXct("2009-08-03 12:05:00", tz = "UTC")) expect_identical(ceiling_date(x, "2 hours"), as.POSIXct("2009-08-03 14:00:00", tz = "UTC")) expect_identical(ceiling_date(x, "3 hours"), as.POSIXct("2009-08-03 15:00:00", tz = "UTC")) expect_identical(ceiling_date(x, "2 days"), as.POSIXct("2009-08-05 00:00:00", tz = "UTC")) expect_identical(ceiling_date(x, "3 days"), as.POSIXct("2009-08-04 00:00:00", tz = "UTC")) expect_identical(ceiling_date(x, "10 days"), as.POSIXct("2009-08-11 00:00:00", tz = "UTC")) expect_identical(ceiling_date(z, "5 days"), as.POSIXct("2009-08-26 00:00:00", tz = "UTC")) expect_identical(ceiling_date(z, "10 days"), as.POSIXct("2009-08-31 00:00:00", tz = "UTC")) expect_identical(ceiling_date(x, "2 month"), as.POSIXct("2009-09-01 00:00:00", tz = "UTC")) expect_identical(ceiling_date(x, "2 bimonth"), ceiling_date(x, "4 months")) expect_identical(ceiling_date(x, "2 quarter"), ceiling_date(x, "6 months")) expect_identical(ceiling_date(x, "2 halfyear"), ceiling_date(x, "year")) expect_identical(ceiling_date(x, "2 year"), as.POSIXct("2010-01-01 00:00:00", tz = "UTC")) }) test_that("ceiling_date works for fractional multi-units", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") expect_identical(ceiling_date(x, ".2 secs"), as.POSIXct("2009-08-03 12:01:59.4", tz = "UTC")) expect_identical(ceiling_date(x, ".1s"), as.POSIXct("2009-08-03 12:01:59.3", tz = "UTC")) expect_identical(ceiling_date(x, ".05s"), as.POSIXct("2009-08-03 12:01:59.25", tz = "UTC")) expect_identical(ceiling_date(x, ".5 mins"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) }) test_that("round_date works for each time element", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") expect_equal(round_date(x, "second"), as.POSIXct("2009-08-03 12:01:59", tz = "UTC")) expect_equal(round_date(x, "minute"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_equal(round_date(x, "hour"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_equal(round_date(x, "day"), as.POSIXct("2009-08-04 00:00:00", tz = "UTC")) expect_equal(round_date(x, "week"), as.POSIXct("2009-08-02 00:00:00", tz = "UTC")) expect_equal(round_date(x, "month"), as.POSIXct("2009-08-01 00:00:00", tz = "UTC")) expect_equal(round_date(x, "bimonth"), as.POSIXct("2009-09-01 00:00:00", tz = "UTC")) expect_equal(round_date(x, "quarter"), as.POSIXct("2009-07-01 00:00:00", tz = "UTC")) expect_equal(round_date(x, "halfyear"), as.POSIXct("2009-07-01 00:00:00", tz = "UTC")) expect_equal(round_date(x, "year"), as.POSIXct("2010-01-01 00:00:00", tz = "UTC")) }) test_that("floor_date and ceiling_date work with leap years", { expect_equal( floor_date(ymd_hms(c("2016-02-29 1:2:3", "2016-03-01 10:20:30")), "year"), ymd_hms(c("2016-01-01 0:0:0", "2016-01-01 0:0:0")) ) expect_equal( floor_date(ymd_hms(c("2016-02-29 1:2:3", "2016-03-01 10:20:30"), tz = "America/New_York"), "year"), ymd_hms(c("2016-01-01 0:0:0", "2016-01-01 0:0:0"), tz = "America/New_York") ) expect_equal( ceiling_date(ymd_hms(c("2016-02-29 1:2:3", "2016-03-01 10:20:30")), "year"), ymd_hms(c("2017-01-01 0:0:0", "2017-01-01 0:0:0")) ) expect_equal( ceiling_date(ymd_hms(c("2016-02-29 1:2:3", "2016-03-01 10:20:30"), tz = "America/New_York"), "year"), ymd_hms(c("2017-01-01 0:0:0", "2017-01-01 0:0:0"), tz = "America/New_York") ) }) test_that("round_date works for multi-units", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") expect_equal(round_date(x, "2 second"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_equal(round_date(x, "2 minute"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_equal(round_date(x, "3 mins"), as.POSIXct("2009-08-03 12:03:00", tz = "UTC")) expect_equal(round_date(x, "5 mins"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_equal(round_date(x, "2 hour"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_equal(round_date(x, "5 hour"), as.POSIXct("2009-08-03 10:00:00", tz = "UTC")) expect_equal(round_date(x, "2 days"), as.POSIXct("2009-08-03 00:00:00", tz = "UTC")) expect_equal(round_date(x, "2 months"), as.POSIXct("2009-09-01 00:00:00", tz = "UTC")) expect_equal(round_date(x, "bimonth"), round_date(x, "2 months")) expect_equal(round_date(x, "bimonth"), round_date(x, "4 months")) expect_equal(round_date(x, "quarter"), round_date(x, "3 months")) expect_equal(round_date(x, "halfyear"), round_date(x, "6 months")) expect_equal(round_date(x, "3 years"), as.POSIXct("2010-01-01 00:00:00", tz = "UTC")) expect_equal(round_date(x, "4 years"), as.POSIXct("2008-01-01 00:00:00", tz = "UTC")) }) test_that("round_date works for fractional multi-units", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") expect_identical(round_date(x, ".2 secs"), as.POSIXct("2009-08-03 12:01:59.2", tz = "UTC")) expect_identical(round_date(x, ".1s"), as.POSIXct("2009-08-03 12:01:59.2", tz = "UTC")) expect_identical(round_date(x, ".05s"), as.POSIXct("2009-08-03 12:01:59.25", tz = "UTC")) expect_identical(round_date(x, ".5 mins"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) }) test_that("floor_date handles vectors", { x <- as.POSIXct(c( "2009-08-03 12:01:59.23", "2010-08-03 12:01:59.23" ), tz = "UTC") expect_identical( floor_date(x, "second"), as.POSIXct(c("2009-08-03 12:01:59", "2010-08-03 12:01:59"), tz = "UTC") ) expect_identical( floor_date(x, "minute"), as.POSIXct(c("2009-08-03 12:01:00", "2010-08-03 12:01:00"), tz = "UTC") ) expect_identical( floor_date(x, "hour"), as.POSIXct(c("2009-08-03 12:00:00", "2010-08-03 12:00:00"), tz = "UTC") ) expect_identical( floor_date(x, "day"), as.POSIXct(c("2009-08-03 00:00:00", "2010-08-03 00:00:00"), tz = "UTC") ) expect_identical( floor_date(x, "week"), as.POSIXct(c("2009-08-02 00:00:00", "2010-08-01 00:00:00"), tz = "UTC") ) expect_identical( floor_date(x, "month"), as.POSIXct(c("2009-08-01 00:00:00", "2010-08-01 00:00:00"), tz = "UTC") ) expect_identical( floor_date(x, "year"), as.POSIXct(c("2009-01-01 00:00:00", "2010-01-01 00:00:00"), tz = "UTC") ) }) test_that("ceiling_date handles vectors", { x <- as.POSIXct(c("2009-08-03 12:01:59.23", "2010-08-03 12:01:59.23"), tz = "UTC") expect_identical( ceiling_date(x, "second"), as.POSIXct(c("2009-08-03 12:02:00", "2010-08-03 12:02:00"), tz = "UTC") ) expect_identical( ceiling_date(x, "minute"), as.POSIXct(c("2009-08-03 12:02:00", "2010-08-03 12:02:00"), tz = "UTC") ) expect_identical( ceiling_date(x, "hour"), as.POSIXct(c("2009-08-03 13:00:00", "2010-08-03 13:00:00"), tz = "UTC") ) expect_identical( ceiling_date(x, "day"), as.POSIXct(c("2009-08-04 00:00:00", "2010-08-04 00:00:00"), tz = "UTC") ) expect_identical( ceiling_date(x, "week"), as.POSIXct(c("2009-08-09 00:00:00", "2010-08-08 00:00:00"), tz = "UTC") ) expect_identical( ceiling_date(x, "month"), as.POSIXct(c("2009-09-01 00:00:00", "2010-09-01 00:00:00"), tz = "UTC") ) expect_identical( ceiling_date(x, "year"), as.POSIXct(c("2010-01-01 00:00:00", "2011-01-01 00:00:00"), tz = "UTC") ) }) test_that("round_date handles vectors", { x <- as.POSIXct(c("2009-08-03 12:01:59.23", "2010-08-03 12:01:59.23"), tz = "UTC") expect_identical( round_date(x, "second"), as.POSIXct(c( "2009-08-03 12:01:59", "2010-08-03 12:01:59" ), tz = "UTC") ) expect_identical( round_date(x, "minute"), as.POSIXct(c( "2009-08-03 12:02:00", "2010-08-03 12:02:00" ), tz = "UTC") ) expect_identical( round_date(x, "hour"), as.POSIXct(c( "2009-08-03 12:00:00", "2010-08-03 12:00:00" ), tz = "UTC") ) expect_identical( round_date(x, "day"), as.POSIXct(c( "2009-08-04 00:00:00", "2010-08-04 00:00:00" ), tz = "UTC") ) expect_identical( round_date(x, "week"), as.POSIXct(c( "2009-08-02 00:00:00", "2010-08-01 00:00:00" ), tz = "UTC") ) expect_identical( round_date(x, "month"), as.POSIXct(c( "2009-08-01 00:00:00", "2010-08-01 00:00:00" ), tz = "UTC") ) expect_identical( round_date(x, "year"), as.POSIXct(c( "2010-01-01 00:00:00", "2011-01-01 00:00:00" ), tz = "UTC") ) }) test_that("floor_date works for a variety of formats", { x <- as.POSIXct("2009-08-03 12:01:59", tz = "UTC") expect_equal( floor_date(x, "minute"), as.POSIXct("2009-08-03 12:01:00", tz = "UTC") ) expect_equal( floor_date(as.Date(x), "month"), as.Date("2009-08-01") ) expect_equal( floor_date(as.Date(x), "bimonth"), ymd("2009-07-01") ) expect_equal( floor_date(as.Date(x), "quarter"), ymd("2009-07-01") ) expect_equal( floor_date(as.Date(x), "halfyear"), ymd("2009-07-01") ) expect_equal( floor_date(as.POSIXlt(x), "minute"), as.POSIXlt(as.POSIXct("2009-08-03 12:01:00", tz = "UTC")) ) }) test_that("ceiling_date works for a variety of formats", { x <- as.POSIXct("2009-08-03 12:01:59", tz = "UTC") expect_equal( ceiling_date(x, "minute"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC") ) expect_equal( ceiling_date(as.Date(x), "month"), as.Date("2009-09-01") ) expect_equal( ceiling_date(as.Date(x), "bimonth"), ymd("2009-09-01") ) expect_equal( ceiling_date(as.Date(x), "quarter"), ymd("2009-10-01") ) expect_equal( ceiling_date(as.Date(x), "halfyear"), ymd("2010-01-01") ) expect_equal( ceiling_date(as.POSIXlt(x), "minute"), as.POSIXlt(as.POSIXct("2009-08-03 12:02:00", tz = "UTC" )) ) }) test_that("round_date works for a variety of formats", { x <- as.POSIXct("2009-08-03 12:01:59", tz = "UTC") expect_equal(round_date(x, "minute"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_equal(round_date(as.Date(x), "month"), as.Date("2009-08-01")) expect_equal( # Workaround for https://github.com/r-lib/testthat/issues/1710 structure(round_date(as.POSIXlt(x), "minute"), balanced = NULL), structure(as.POSIXlt(as.POSIXct("2009-08-03 12:02:00", tz = "UTC")), balanced = NULL)) ## https://github.com/tidyverse/lubridate/issues/1008 y <- as.Date("2021-01-31") expect_equal(round_date(y, "month"), as.Date("2021-02-01")) }) test_that("rounding works across DST", { ## https://github.com/tidyverse/lubridate/issues/399 tt <- ymd("2016-03-27", tz = "Europe/Helsinki") expect_equal(ceiling_date(tt, "month"), as.POSIXct("2016-04-01", tz = "Europe/Helsinki")) expect_equal(ceiling_date(tt, "day"), as.POSIXct("2016-03-27", tz = "Europe/Helsinki")) tt <- ymd("2016-03-28", tz = "Europe/Helsinki") expect_equal(floor_date(tt, "month"), as.POSIXct("2016-03-01", tz = "Europe/Helsinki")) tt <- ymd_hms("2016-03-27 05:00:00", tz = "Europe/Helsinki") expect_equal(floor_date(tt, "day"), as.POSIXct("2016-03-27", tz = "Europe/Helsinki")) ## https://github.com/tidyverse/lubridate/issues/605 x <- ymd_hms("2017-11-05 23:59:03", tz = "America/New_York") expect_equal(ceiling_date(x, "day"), as.POSIXct("2017-11-06", tz = "America/New_York")) }) test_that("Ceiling for partials (Date) rounds up on boundary", { expect_identical(ceiling_date(as.Date("2012-09-27"), "day"), ymd("2012-09-28")) expect_identical(ceiling_date(as.Date("2012-09-01"), "day"), ymd("2012-09-02")) expect_identical(ceiling_date(as.Date("2012-09-01"), "2 days"), ymd("2012-09-03")) }) test_that("Ceiling for Date returns date when unit level is higher than day", { expect_true(is.Date(ceiling_date(ymd("20160927"), "year"))) expect_true(is.Date(ceiling_date(ymd("20160927"), "halfyear"))) expect_true(is.Date(ceiling_date(ymd("20160927"), "quarter"))) expect_true(is.Date(ceiling_date(ymd("20160927"), "bimonth"))) expect_true(is.Date(ceiling_date(ymd("20160927"), "month"))) expect_true(is.Date(ceiling_date(ymd("20160927"), "week"))) expect_true(is.Date(ceiling_date(ymd("20160927"), "day"))) expect_true(is.POSIXct(ceiling_date(ymd("20160927"), "hour"))) expect_true(is.POSIXct(ceiling_date(ymd("20160927"), "minute"))) expect_true(is.POSIXct(ceiling_date(ymd("20160927"), "second"))) }) test_that("Ceiling for POSIXct always returns POSIXct", { expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "year"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "halfyear"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "quarter"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "bimonth"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "month"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "week"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "day"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "hour"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "minute"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "second"))) }) test_that("ceiling_date does not round up dates that are already on a boundary", { expect_equal(ceiling_date(ymd_hms("2012-09-01 00:00:00"), "month"), as.POSIXct("2012-09-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 00:00:00"), "year"), as.POSIXct("2012-01-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 00:00:00"), "2 year"), as.POSIXct("2012-01-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 00:00:00"), "3 year"), as.POSIXct("2013-01-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 00:00:00"), "5 year"), as.POSIXct("2015-01-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 01:00:00"), "second"), ymd_hms("2012-01-01 01:00:00")) expect_equal(ceiling_date(ymd_hms("2012-01-01 01:00:00"), "2 second"), ymd_hms("2012-01-01 01:00:00")) expect_equal( ceiling_date(ymd_hms("2012-01-01 01:00:00"), "2 second", change_on_boundary = T), ymd_hms("2012-01-01 01:00:02") ) expect_equal(ceiling_date(ymd_hms("2012-01-01 01:00:00"), "5 second"), ymd_hms("2012-01-01 01:00:00")) expect_equal(ceiling_date(ymd_hms("2012-01-01 00:00:00"), "bimonth"), ymd_hms("2012-01-01 00:00:00")) }) test_that("ceiling_date does round up dates on a boundary with change_on_boundary=TRUE", { expect_equal(ceiling_date(as.Date("2012-09-27"), "day", TRUE), as.Date("2012-09-28")) expect_equal(ceiling_date(as.Date("2012-09-01"), "month", TRUE), as.Date("2012-10-01")) expect_equal(ceiling_date(ymd_hms("2012-09-01 00:00:00"), "month", TRUE), ymd("2012-10-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-09-01 00:00:00"), "bimonth", TRUE), ymd("2012-11-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 00:00:00"), "year", TRUE), as.POSIXct("2013-01-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 01:00:00"), "hour", TRUE), ymd_hms("2012-01-01 02:00:00")) expect_equal(ceiling_date(ymd_hms("2012-01-01 00:00:00"), "day", TRUE), ymd("2012-01-02", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 01:00:00"), "second", TRUE), ymd_hms("2012-01-01 01:00:01")) }) test_that("floor_date does not round down dates that are already on a boundary", { expect_equal(floor_date(as.Date("2012-09-27"), "day"), as.Date("2012-09-27")) }) test_that("round_date does not round dates that are already on a boundary", { expect_equal(round_date(as.Date("2012-09-27"), "day"), as.Date("2012-09-27")) }) test_that("ceiling_date returns input of length zero when given input of length zero", { x <- structure(vector(mode = "numeric"), class = c("POSIXct", "POSIXt")) expect_equal(ceiling_date(x), x) }) test_that("floor_date returns input of length zero when given input of length zero", { x <- structure(vector(mode = "numeric"), class = c("POSIXct", "POSIXt")) expect_equal(floor_date(x), x) }) test_that("round_date returns input of length zero when given input of length zero", { x <- structure(vector(mode = "numeric"), class = c("POSIXct", "POSIXt")) expect_equal(round_date(x), x) }) test_that("round_date behaves correctly on 60th second", { ## (bug #217) x <- ymd_hms("2013-12-01 23:59:59.9999") expect_equal( round_date(x, unit = "second"), ymd("2013-12-02", tz = "UTC") ) second(x) <- 60 expect_equal(x, ymd("2013-12-02", tz = "UTC")) }) test_that("round_date and ceiling_date skip day time gap", { ## (#240) tz <- "Europe/Amsterdam" times <- ymd_hms("2013-03-31 01:00:00 CET", "2013-03-31 01:15:00 CEST", "2013-03-31 01:30:00 CEST", "2013-03-31 01:45:00 CEST", "2013-03-31 03:00:00 CEST", "2013-03-31 03:15:00 CEST", tz = tz ) round <- ymd_hms("2013-03-31 01:00:00 CET", "2013-03-31 01:00:00 CEST", "2013-03-31 03:00:00 CEST", "2013-03-31 03:00:00 CEST", "2013-03-31 03:00:00 CEST", "2013-03-31 03:00:00 CEST", tz = tz ) expect_equal(round_date(times, "hour"), round) ceiling <- ymd_hms("2013-03-31 01:00:00 CET", "2013-03-31 03:00:00 CEST", "2013-03-31 03:00:00 CEST", "2013-03-31 03:00:00 CEST", "2013-03-31 03:00:00 CEST", "2013-03-31 04:00:00 CEST", tz = tz ) expect_equal(ceiling_date(times, "hour"), ceiling) tz <- "America/Chicago" x <- ymd_hms(c( "2014-03-09 00:00:00", "2014-03-09 00:29:59", "2014-03-09 00:30:00", "2014-03-09 00:59:59", "2014-03-09 01:35:00", "2014-03-09 03:15:00", "2014-11-02 00:30:00", "2014-11-02 00:59:59", "2014-11-02 01:35:00", "2014-11-02 02:15:00", "2014-11-02 02:45:00" ), tz = tz ) y <- as.POSIXct(c( "2014-03-09 00:00:00", "2014-03-09 00:00:00", "2014-03-09 01:00:00", "2014-03-09 01:00:00", "2014-03-09 03:00:00", "2014-03-09 03:00:00", "2014-11-02 01:00:00", "2014-11-02 01:00:00", "2014-11-02 02:00:00", "2014-11-02 02:00:00", "2014-11-02 03:00:00" ), tz = tz ) ## ymd_hms("2014-11-02 01:35:00", tz = tz) ## force_tz(ymd_hms("2014-11-02 01:35:00"), tzone = "America/Chicago") ## round_date(ymd_hms("2014-11-02 01:35:00", tz = "America/Chicago"), "hour") expect_equal(round_date(x, "hour"), y) }) test_that("rounding works within repeated DST", { ## "2014-11-02 00:00:00 CDT" ref <- ymd_hms("2014-11-02 00:00:00", tz = "America/Chicago") expect_equal(round_date(ref + dminutes(25), "hour"), ref) expect_equal(round_date(ref + dminutes(35), "hour"), ref + dhours(1)) expect_equal(round_date(ref + dhours(1) + dminutes(25), "hour"), ref + dhours(1)) expect_equal(round_date(ref + dhours(1) + dminutes(35), "ahour"), ref + dhours(2)) expect_equal(round_date(ref + dhours(2) + dminutes(20), "hour"), ref + dhours(2)) expect_equal(round_date(ref + dhours(2) + dminutes(35), "hour"), ref + dhours(3)) expect_equal(round_date(ref + duration("1H 35M 2S"), "minute"), ref + duration("1H 35M")) expect_equal(round_date(ref + duration("1H 35M 35S"), "minute"), ref + duration("1H 36M")) expect_equal(round_date(ref + duration("2H 35M 2S"), "minute"), ref + duration("2H 35M")) }) test_that("ceiling_date, round_date and floor_date behave correctly with NA", { ## (bug #486) x <- ymd_hms("2009-08-03 12:01:59.23", tz = "UTC") + (0:1) * days() x[2] <- NA expect_equal(ceiling_date(x, unit = "day"), ymd(c("2009-08-04", NA), tz = "UTC")) expect_equal(ceiling_date(x, unit = "seconds"), ymd_hms(c("2009-08-03 12:02:00", NA), tz = "UTC")) expect_equal(ceiling_date(x, unit = "months"), ymd(c("2009-09-01", NA), tz = "UTC")) expect_equal(floor_date(x, unit = "day"), ymd(c("2009-08-03", NA), tz = "UTC")) expect_equal(floor_date(x, unit = "months"), ymd(c("2009-08-01", NA), tz = "UTC")) expect_equal(round_date(x, unit = "minute"), ymd_hms(c("2009-08-03 12:02:00", NA), tz = "UTC")) }) test_that("floor_date works for seasons", { dts <- ymd_hms(sprintf("2017-%d-02 0:34:3", 1:12)) expect_equal(month(floor_date(dts, "season")), c(12, 12, 3, 3, 3, 6, 6, 6, 9, 9, 9, 12)) dts <- force_tz(dts, "America/New_York") expect_equal(month(floor_date(dts, "season")), c(12, 12, 3, 3, 3, 6, 6, 6, 9, 9, 9, 12)) }) test_that("ceiling_date works for seasons", { dts <- ymd_hms(sprintf("2017-%d-02 0:34:3", 1:12)) expect_equal(month(ceiling_date(dts, "season")), c(3, 3, 6, 6, 6, 9, 9, 9, 12, 12, 12, 3)) dts <- force_tz(dts, "America/New_York") expect_equal(month(ceiling_date(dts, "season")), c(3, 3, 6, 6, 6, 9, 9, 9, 12, 12, 12, 3)) }) test_that("round on week respects week_start", { date <- ymd("2017-05-07") ## sunday ct <- as.POSIXct("2010-02-03 13:45:59", tz = "America/New_York", format = "%Y-%m-%d %H:%M:%S") ## Wednesday expect_equal(wday(floor_date(ct, "week", week_start = 1)), 2) expect_equal(wday(floor_date(ct, "week", week_start = 2)), 3) expect_equal(wday(floor_date(ct, "week", week_start = 5)), 6) expect_equal(wday(floor_date(ct, "week", week_start = 7)), 1) expect_equal(wday(floor_date(date, "week", week_start = 1)), 2) expect_equal(wday(floor_date(date, "week", week_start = 2)), 3) expect_equal(wday(floor_date(date, "week", week_start = 5)), 6) expect_equal(wday(floor_date(date, "week", week_start = 7)), 1) expect_equal(wday(floor_date(ct, "week", week_start = 1), week_start = 1), 1) expect_equal(wday(floor_date(ct, "week", week_start = 2), week_start = 2), 1) expect_equal(wday(floor_date(ct, "week", week_start = 5), week_start = 5), 1) expect_equal(wday(floor_date(ct, "week", week_start = 7), week_start = 7), 1) expect_equal(wday(floor_date(date, "week", week_start = 1), week_start = 1), 1) expect_equal(wday(floor_date(date, "week", week_start = 2), week_start = 2), 1) expect_equal(wday(floor_date(date, "week", week_start = 5), week_start = 5), 1) expect_equal(wday(floor_date(date, "week", week_start = 7), week_start = 7), 1) expect_equal(wday(ceiling_date(ct, "week", week_start = 1)), 2) expect_equal(wday(ceiling_date(ct, "week", week_start = 2)), 3) expect_equal(wday(ceiling_date(ct, "week", week_start = 5)), 6) expect_equal(wday(ceiling_date(ct, "week", week_start = 7)), 1) expect_equal(wday(ceiling_date(date, "week", week_start = 1)), 2) expect_equal(wday(ceiling_date(date, "week", week_start = 2)), 3) expect_equal(wday(ceiling_date(date, "week", week_start = 5)), 6) expect_equal(wday(ceiling_date(date, "week", week_start = 7)), 1) expect_equal(wday(ceiling_date(ct, "week", week_start = 1), week_start = 1), 1) expect_equal(wday(ceiling_date(ct, "week", week_start = 2), week_start = 2), 1) expect_equal(wday(ceiling_date(ct, "week", week_start = 5), week_start = 5), 1) expect_equal(wday(ceiling_date(ct, "week", week_start = 7), week_start = 7), 1) expect_equal(wday(ceiling_date(date, "week", week_start = 1), week_start = 1), 1) expect_equal(wday(ceiling_date(date, "week", week_start = 2), week_start = 2), 1) expect_equal(wday(ceiling_date(date, "week", week_start = 5), week_start = 5), 1) expect_equal(wday(ceiling_date(date, "week", week_start = 7), week_start = 7), 1) expect_equal(wday(round_date(ct, "week", week_start = 1)), 2) expect_equal(wday(round_date(ct, "week", week_start = 2)), 3) expect_equal(wday(round_date(ct, "week", week_start = 5)), 6) expect_equal(wday(round_date(ct, "week", week_start = 7)), 1) expect_equal(wday(round_date(date, "week", week_start = 1)), 2) expect_equal(wday(round_date(date, "week", week_start = 2)), 3) expect_equal(wday(round_date(date, "week", week_start = 5)), 6) expect_equal(wday(round_date(date, "week", week_start = 7)), 1) expect_equal(wday(round_date(ct, "week", week_start = 1), week_start = 1), 1) expect_equal(wday(round_date(ct, "week", week_start = 2), week_start = 2), 1) expect_equal(wday(round_date(ct, "week", week_start = 5), week_start = 5), 1) expect_equal(wday(round_date(ct, "week", week_start = 7), week_start = 7), 1) expect_equal(wday(round_date(date, "week", week_start = 1), week_start = 1), 1) expect_equal(wday(round_date(date, "week", week_start = 2), week_start = 2), 1) expect_equal(wday(round_date(date, "week", week_start = 5), week_start = 5), 1) expect_equal(wday(round_date(date, "week", week_start = 7), week_start = 7), 1) }) test_that("rounding works when week_start = name of week day", { date <- ymd("2017-05-07") ## sunday ct <- as.POSIXct("2010-02-03 13:45:59", tz = "America/New_York", format = "%Y-%m-%d %H:%M:%S") ## Wednesday expect_identical(floor_date(ct, "week", week_start = "Monday"), floor_date(ct, "week", week_start = 1)) expect_identical(floor_date(ct, "week", week_start = "Tuesday"), floor_date(ct, "week", week_start = 2)) expect_identical(ceiling_date(ct, "week", week_start = "Monday"), ceiling_date(ct, "week", week_start = 1)) expect_identical(ceiling_date(ct, "week", week_start = "Friday"), ceiling_date(ct, "week", week_start = 5)) expect_identical(ceiling_date(ct, "week", week_start = "Mond"), ceiling_date(ct, "week", week_start = 1)) expect_identical(ceiling_date(ct, "week", week_start = "Fri"), ceiling_date(ct, "week", week_start = 5)) expect_identical(round_date(ct, "week", week_start = "Monday"), round_date(ct, "week", week_start = 1)) expect_identical(round_date(ct, "week", week_start = "Sunday"), round_date(ct, "week", week_start = 7)) expect_identical(round_date(ct, "week", week_start = "Mon"), round_date(ct, "week", week_start = 1)) expect_identical(round_date(ct, "week", week_start = "Sund"), round_date(ct, "week", week_start = 7)) }) test_that("wday extract and update: week_start can be a week day", { d <- ymd("2017-01-02") # Monday p <- as_datetime(d) expect_identical(wday(d, week_start = "Tue"), 7) expect_identical(wday(p, week_start = "Tue"), 7) expect_identical(wday(d, week_start = "Monday"), 1) expect_identical(wday(p, week_start = "Monday"), 1) expect_identical(wday(2, week_start = "Monday"), 1) expect_identical(wday(2, week_start = "Monday"), wday(2, week_start = 1)) wday(d) <- "Tue" expect_identical(wday(d), 3) # ignore week_start when value is a character wday(d, week_start = 1) <- "Tue" expect_identical(wday(d), 3) wday(p, week_start = 2) <- "Sunday" expect_identical(wday(p), 1) wday(p) <- "Wednesday" expect_identical(wday(p), 4) wday(d) <- 4 expect_identical(wday(d), 4) wday(d, week_start = 2) <- 4 expect_identical(wday(d, week_start = 2), 4) wday(p) <- 5 expect_identical(wday(p), 5) }) test_that("rounding works for dates < 1970", { expect_equal(round_date(ymd_hms("1957-12-01 14:00:00 UTC"), "month"), ymd("1957-12-01", tz = "UTC")) expect_equal(round_date(ymd_hms("1958-01-31 09:59:59 UTC"), "month"), ymd("1958-02-01", tz = "UTC")) }) test_that("rounding of fractional second works around origin", { ## #789 seq <- seq(0, 500, 33)/1000 time <- lubridate::origin - seq rnd <- round_date(time, ".033s") expect_true(all(unclass(rnd) > -.52)) time <- lubridate::origin + seq rnd <- round_date(time, ".033s") expect_true(all(unclass(rnd) < .5)) ## plot(time, rnd) }) test_that("ceiling of dates works correctly before 1970", { #1107 dates <- ymd('1969-01-01') + years(c(0:2)) expect_equal(ceiling_date(dates, 'month', change_on_boundary = FALSE), dates) expect_equal(ceiling_date(dates, unit = 'month', change_on_boundary = TRUE), dates + months(1)) })