test_that("test all variants of creating a CFtime object and useful functions", { # Call CFtime() without arguments expect_error(CFtime()) # Call CFtime() with an invalid definition expect_error(CFtime("foo")) expect_error(CFtime("zxcv since 1991-01-01")) expect_error(CFtime("days since -991-01-01")) # Call CFtime() with a valid definition and an invalid calendar expect_error(CFtime("days since 1991-01-01", "foo")) expect_equal(calendar(CFtime("days since 1991-01-01", NULL, NULL)), "standard") expect_equal(definition(CFtime("days since 1991-01-01", NULL, NULL)), "days since 1991-01-01") expect_equal(resolution(CFtime("days since 1991-01-01", NULL, NULL)), NA_real_) # Call CFtime() with a valid definition and calendar but faulty offsets expect_error(CFtime("days since 1991-01-01", "standard", c(0:10, NA))) # CFtime() with only a definition t <- CFtime("d per 1991-01-01") expect_equal(origin(t)[1:3], data.frame(year = 1991, month = 1, day = 1)) expect_equal(unit(t), "days") expect_equal(calendar(t), "standard") expect_equal(length(offsets(t)), 0L) # CFtime with only a definition and a calendar t <- CFtime("d per 1991-01-01", "julian") expect_match(capture_output(t$print()), "^CF calendar:") expect_match(capture_output(t$print()), "Elements: \\(no elements\\)\\n Bounds : \\(not set\\)$") expect_equal(origin(t)[1:3], data.frame(year = 1991, month = 1, day = 1)) expect_equal(unit(t), "days") expect_equal(calendar(t), "julian") expect_equal(length(offsets(t)), 0L) # CFtime with a single offset t <- t + 15 expect_equal(as_timestamp(t, "date"), "1991-01-16") expect_match(capture_output(t$print()), "Elements: 1991-01-16 \\n Bounds : not set$") # Invalid offsets expect_error(CFtime("d per 1991-01-01", "julian", c(TRUE, FALSE, FALSE))) # Character offsets t <- CFtime("hours since 2023-01-01", "360_day", "2023-04-30T23:00") expect_equal(range(t), c("2023-01-01 00:00:00", "2023-04-30 23:00:00")) expect_equal(length(as_timestamp(t, "timestamp")), 4 * 30 * 24) t$bounds <- TRUE expect_equal(t$range(bounds = TRUE), c("2022-12-30 23:30:00", "2023-04-30 23:30:00")) expect_warning(t <- CFtime("days since 2023-01-01", "366_day", c("2023-01-01", "2023-04-13", "2023-10-30", "2023-05-12"))) expect_equal(range(t), c("2023-01-01", "2023-10-30")) # Merge two CFtime instances / extend offsets t1 <- CFtime("hours since 2001-01-01", "360_day", 0:99) t2 <- CFtime("hours since 2001-01-01", "julian", 100:199) expect_false(t1 == t2) expect_error(t1 + t2) t2 <- CFtime("hours since 2001-01-01", "360_day", 100:199) expect_false(t1 == t2) expect_equal(length(offsets(t1 + t2)), 200) expect_equal(length(offsets(t1 + 100:199)), 200) t1 <- CFtime("days since 2022-01-01", "365_day", 0:364) t2 <- CFtime("days since 2023-01-01", "365_day", 0:364) expect_match(capture_output(t1$print()), "between 365 elements\\)\\n Bounds : not set$") expect_true(length(offsets(t1 + t2)) == 730) expect_true(all(range(diff(offsets(t1 + t2))) == c(1, 1))) expect_warning(t3 <- t2 + t1) expect_true(length(offsets(t3)) == 730) expect_false((range(diff(offsets(t3))) == c(1, 1))[1]) t2 <- t1 + c("2023-01-01", "2023-01-02") expect_match(capture_output(t1$print()), "between 365 elements\\)\\n Bounds : not set$") expect_equal(t2$resolution, 1) # Timezones expect_equal(timezone(t1), "+0000") expect_false(grepl("+0000", capture_output(t1$print()), fixed = TRUE)) t1 <- CFtime("days since 2022-01-01 00:00:00+04", "365_day", 0:364) expect_true(grepl("+0400", capture_output(t1$print()), fixed = TRUE)) # Time series completeness t <- CFtime("d per 1991-01-01", "julian") expect_error(is_complete("zxcv")) expect_true(is.na(is_complete(t))) expect_true(is_complete(t1)) mid_months <- c("1950-01-16T12:00:00", "1950-02-15T00:00:00", "1950-03-16T12:00:00", "1950-04-16T00:00:00", "1950-05-16T12:00:00", "1950-06-16T00:00:00", "1950-07-16T12:00:00", "1950-08-16T12:00:00", "1950-09-16T00:00:00", "1950-10-16T12:00:00", "1950-11-16T00:00:00", "1950-12-16T12:00:00") t <- CFtime("days since 1950-01-01", "standard", mid_months) expect_true(is_complete(t)) ty <- CFtime("years since 2020-01-01", "standard", 0:19) expect_true(is_complete(ty)) ty <- ty + 30:39 expect_false(is_complete(ty)) # Range t <- CFtime("days since 2001-01-01") expect_equal(range(t), c(NA_character_, NA_character_)) t <- t + 0:1 expect_error(range(t, 123)) expect_error(range(t, c("asd %d", "%F"))) expect_equal(range(t, "%Y-%B-%Od"), c("2001-January-01", "2001-January-02")) # Range on unsorted offsets random <- runif(100, min = 1, max = 99) expect_warning(t <- CFtime("days since 2001-01-01", offsets = c(0, random[1:50], 100, random[51:100]))) expect_equal(range(t), c("2001-01-01", paste0(as.Date("2001-01-01") + 100))) # Subsetting t <- CFtime("hours since 2023-01-01 00:00:00", "standard", 0:239) expect_error(slice("zxcv")) expect_true(all(slice(t, c("2023-01-01", "2023-02-01")))) expect_true(length(which(slice(t, c("2023-01-01", "2023-05-01")))) == 240) expect_true(length(which(slice(t, c("2023-01-01 00:00", "2023-01-01 04:00")))) == 4) expect_true(length(which(slice(t, c("2023-01-01 04:00", "2023-01-01 00:00")))) == 4) # extremes in reverse order expect_true(slice(t, c("2022-01-01", "2023-01-02"))[1]) # early extreme before timeseries expect_true(all(!slice(t, c("2023-02-01", "2023-03-01")))) # both extremes outside time series expect_equal(sum(slice(t, c("2023-01-01 00:00", "2023-01-01 04:00", "2023-01-02 00:00"))), 24) expect_equal(sum(slice(t, c("2023-01-01 00:00", "2023-01-01 04:00", "2023-01-02 00:00"), TRUE)), 25) }) test_that("Leap years on some calendars", { t <- CFTime$new("days since 2025-01-01", "360_day") expect_true(all(!t$cal$leap_year(c(2000:2025)))) t <- CFTime$new("days since 2025-01-01", "366_day") expect_true(all(t$cal$leap_year(c(2000:2025)))) }) test_that("Working with packages and files", { lf <- list.files(path = system.file("extdata", package = "CFtime"), full.names = TRUE) if (requireNamespace("ncdfCF")) lapply(lf, function(f) { nc <- ncdfCF::open_ncdf(f) expect_s3_class(nc[["time"]]$values, "CFTime") }) })