Blame | Last modification | View Log | Download | RSS feed
"dates"<-function(x, ...)floor(chron(dates. = x, ...))"Math.dates" <-function(x, ...){ok <- switch(.Generic,trunc = ,round = ,signif = ,ceiling = ,floor = TRUE,FALSE)if(!ok)stop(paste(.Generic, "not defined for dates objects"))cl <- oldClass(x)class(x) <- NULLout <- NextMethod(.Generic)class(out) <- clout}"Ops.dates" <-function(e1, e2){ok <- switch(.Generic,"+" = ,"-" = ,"<" = ,">" = ,"==" = ,"!=" = ,"<=" = ,">=" = TRUE,FALSE)if(nargs() == 1) {## unary operators (only + is valid)if(.Generic == "+")return(e1)elsestop(paste("unary", .Generic, "not defined for chron objects"))}if(!ok)stop(paste(.Generic, "not defined for chron objects"))dates.flg <- nchar(.Method)if(is.character(e1)) {e1 <- chron(e1, format = attr(e2, "format"), origin = origin(e2))dates.flg[1] <- TRUE}if(is.character(e2)) {e2 <- chron(e2, format = attr(e1, "format"), origin = origin(e1))dates.flg[2] <- TRUE}scalar <- !all(dates.flg) # scalar operand?o1 <- origin(e1)o2 <- origin(e2)if(!scalar) {if(.Generic == "+")stop("chron objects may not be added together")if(any(o1 - o2)) {warning("different origin in dates arithmetic")origin(e2) <- o2 <- o1}}val <- NextMethod(.Generic)boolean <- match(.Generic, c("==", "!=", ">", ">=", "<", "<="),nomatch = 0)if(boolean)return(val) # make sure origin wasn't droppedif(!inherits(val, "dates")) {attr(val, "origin") <- if(dates.flg[1]) o1 else o2class(val) <- unique(c(.Class, class(val)))}tms <- as.vector(val)tmp <- tms - floor(tms)## If a fractional scalar operand, then dates become chronsif(scalar && length(tmp <- tmp[!is.na(tmp)]) && any(tmp != 0)) {if(length(fmt.val <- attr(val, "format")) < 2)attr(val, "format") <- c(fmt.val, "h:m:s")class(val) <- c("chron", "dates", "times")}## dates - dates is daysif(!scalar && inherits(val, "dates")) {if(length(fmt.val <- attr(val, "format")) < 2)attr(val, "format") <- "h:m:s"else attr(val, "format") <- rev(attr(val, "format"))[[1]]attr(val, "origin") <- NULLval <- times(val)}val}"Summary.dates" <-function(x, ...){ok <- switch(.Generic,max = ,min = ,range = TRUE,FALSE)if(!ok)stop(paste(.Generic,"not defined for objects that inherit from dates"))val <- NextMethod(.Generic)attr(val, "origin") <- origin(x)class(val) <- class(x)val}"[<-.dates" <-function(x, ..., value){if(!as.logical(length(value)))return(x) # as per p.104 in the blue bookif(!is.numeric(value) && !is.character(value) && !all(is.na(value)))stop("replacement of/with chron objects must be with times objects")ox <- origin(x)fmt <- attr(x, "format")if(!inherits(value, "dates"))value <- chron(value, format = fmt, origin = ox)else if(any(ox != origin(value)))origin(value) <- oxcl <- oldClass(x)class(x) <- class(value) <- NULLx <- NextMethod(.Generic)attr(x, "format") <- fmtattr(x, "origin") <- oxclass(x) <- clx}"all.equal.dates" <-function(..., tolerance = 1/(10 * 24 * 60 * 60))NextMethod("all.equal", ..., tolerance = tolerance)as.data.frame.dates <- as.data.frame.vector"c.dates" <-function(..., recursive = FALSE){## output will have the format and origin corresponding to the## argument with earliest origindots <- list(...)is.dts <- unlist(lapply(dots, inherits, "dates"))o <- matrix(unlist(lapply(dots, origin)), nrow = 3)all.orig <- julian(o[1, ], o[2, ], o[3, ], origin = c(0, 0, 0))earliest <- min(all.orig)mdy <- month.day.year(earliest, origin = c(0, 0, 0))orig <- c(mdy$month, mdy$day, mdy$year)n <- length(dots)fmt <- attr(dots[[(1:n)[is.dts][match(earliest, all.orig)]]], "format")out <- vector("list", length = n)for(i in 1:n) {x <- dots[[i]]## note that NA's don't need any further processingif(!all(is.na(x))) {if(is.dts[i]) {if(any(origin(x) != orig))origin(x) <- orig}else x <- chron(x, format = fmt, origin = orig)}out[i] <- list(x)}out <- chron(unlist(out, use.names = FALSE),origin = orig, format = fmt)out}"convert.dates" <-function(dates. = NULL, format = "m/d/y", origin., length. = 0, ...){## returns a julian vector given various types of inputif(is.null(dates.) || !length(dates.))return(numeric(length = length.))if(is.numeric(dates.))return(dates.) # assume julian formatif(!is.character(dates.) && all(!is.na(dates.)))stop(paste("object", deparse(substitute(dates.)),"must be numeric or character"))if(!is.character(format)) {## format may be a function or fun nameFUN <- switch(mode(format),name = get(as.character(format), mode = "function"),"function" = format,stop(paste("unrecognized date format",as.character(format))))return(FUN(dates., ...))}if(missing(origin.)&& is.null(origin. <- getOption("chron.origin")))origin. <- c(month = 1, day = 1, year = 1970)## determine sep, order of month, day, year, etc.fmt <- parse.format(format)out <- unpaste(dates., sep = fmt$sep, fnames = fmt$periods,nfields = 3)if(fmt$abb)mo <- as.numeric(out$m)else mo <- match(tolower(substring(out$m, 1, 3)),tolower(month.abb), nomatch = NA)yy <- as.numeric(out$y)dy <- as.numeric(out$d)if(all(is.na(yy) | is.na(dy) | is.na(mo)))if(any(!is.na(as.character(dates.))))stop(paste("format", format, "may be incorrect"))elsereturn(rep(NA, length(dates.)))if(any(!is.na(yy)) && fmt$year.abb){fun <- getOption("chron.year.expand")fun <- switch(mode(fun),"character" = get(fun, mode = "function"),"name" = eval(fun),"function" = fun,stop(paste("cannot expand 2-digit year abbreviation","--you must specify \"chron.year.expand\"","through options()")))yy <- fun(yy, ...)}non.na <- !is.na(mo) # all months between 1 and 12?bad <- seq(along = mo)[non.na][mo[non.na] < 1 | mo[non.na] > 12]if(n.bad <- length(bad)) {if(n.bad > 10)msg <- paste(n.bad, "months out of range set to NA")else msg <- paste("month(s) out of range in positions",paste(bad, collapse = ","), "set to NA")warning(msg)mo[bad] <- NAnon.na[bad] <- FALSE}non.na <- non.na & !is.na(dy)mon.len <- month.length[mo[non.na]]mon.len[leap.year(yy[non.na]) & mo[non.na] == 2] <- 29# leap years!## all days in the proper range (including leap years)?bad <- seq(along = dy)[non.na][dy[non.na] < 1 | dy[non.na] > mon.len]if(n.bad <- length(bad)) {if(n.bad > 10)msg <- paste(n.bad, "days out of range set to NA")else msg <- paste("days(s) out of range in positions",paste(bad, collapse = ","), "set to NA")warning(msg)dy[bad] <- NAnon.na[bad] <- FALSE}return(julian(mo, dy, yy, origin = origin.))}"cut.dates"<-function(x, breaks, labels, start.on.monday = TRUE, ...){if(!inherits(x, "dates"))x <- chron(x)n <- length(breaks) # dates breaks may be either# numeric of characterif(n > 1) {if(!inherits(breaks, "dates"))breaks <- sort(chron(dates = breaks))## make sure x and breaks have same originorg <- origin(x)if(!is.null(o <- origin(breaks)) && any(o != org))origin(breaks) <- orgbreaks <- as.numeric(breaks)if(missing(labels))labels <- paste("Range", seq(along = breaks[-1]))out <- cut.default(x, breaks = breaks, labels = labels)out <- ordered(as.character(out), levels = levels(out),labels = labels)return(out)}if(n < 1) stop(paste(deparse(substitute(breaks)),"must have length > 0"))## breaks is either number or a stringif(is.numeric(breaks)) {x <- as.numeric(x)if(inherits(breaks, "times"))breaks <- unclass(breaks)out <- NextMethod("cut")return(ordered(out))}## we have a character stringvalid <- c("days", "weeks", "months", "years")if(!as.logical(i <- pmatch(breaks[1], valid, 0)))stop(paste("unrecognized time period (", breaks,"), must be one of", paste(valid, collapse = ","),collapse = " "))by <- valid[i]bump <- c(1, 7, 31, 365)[i] # force a full period for last obs.from <- min(x)orig <- origin(x)mdy <- month.day.year(as.numeric(from), origin = orig)from <- switch(by,days = from,weeks = (from - day.of.week(mdy$m, mdy$d, mdy$y)+ as.numeric(start.on.monday)),months = chron(julian(mdy$m, 1, mdy$y, origin = orig)),years = chron(julian(1, 1, mdy$y, origin = orig)))if(from == min(x))from <- from - .Machine$double.epsbreaks <- brk <- seq(from = from, to = max(x) + bump, by = by)breaks <- as.numeric(breaks)n <- length(breaks)x <- as.numeric(x)if(missing(labels)) {labels <-switch(by,days = paste("day", seq(along = breaks[ - n] + 1)),weeks = paste("week", seq(along = breaks[ - n] + 1)),months = paste(as.character(months(brk[ - n] + 1)),substring(as.character(years(brk[ - n] + 1)), 3, 4)),years = substring(as.character(years(brk[ - n] + 1)), 3, 4))}out <- cut.default(x, breaks = breaks, labels = labels, right = FALSE)ordered(as.character(out), levels = levels(out), labels = labels)}"format.dates" <-function(x, format = "m/d/y", origin., simplify = FALSE, ...){if(!all(is.na(x)) && !is.numeric(x))stop(paste("couldn't extract julian dates from object",deparse(substitute(x))))if(is.null(default.orig <- getOption("chron.origin")))default.orig <- c(month = 1, day = 1, year = 1970)att <- attributes(x)if(inherits(x, "dates")) {if(missing(format))format <- switch(mode(att$format),character = ,list = att$format[[1]],name = ,"function" = att$format,NULL = format,stop("invalid output format for dates"))if(missing(origin.))origin. <- att$origin}else if(missing(origin.))origin. <- default.origif(!is.character(format)) {## format may be a functionFUN <- switch(mode(format),"function" = format,name = eval(format),stop(paste("unknown date format",as.character(format))))return(FUN(unclass(x), ...))}v <- month.day.year(floor(unclass(x)), origin = origin.)v$day <- substring(paste("0", v$day, sep = ""),first = nchar(paste(v$day)))if(simplify) {drop.year <- length(unique(v$year[!is.na(v$year)])) <= 1drop.mon <- (simplify > 1 && drop.year&& length(unique(v$mon)) <= 1)if(!drop.mon && !drop.year)drop.day <- TRUE}fmt <- parse.format(format[1])perm <- fmt$periodsif(fmt$abb) {v$month <- substring(paste("0", v$mon, sep = ""),first = nchar(paste(v$mon)))if(fmt$year.abb){v$year <- v$year %% 100v$year <- substring(paste("0", v$year, sep=""),first = nchar(paste(v$year)))}}else {v$month <- if(fmt$mon.abb)month.abb[v$mon]elsemonth.name[v$mon]}sep <- fmt$sepy <- character(length = length(x))if(!simplify)y[] <- paste(v[[perm[1]]], v[[perm[2]]], v[[perm[3]]], sep = sep)else {## simplify (drop year/month when all equal)if(drop.mon) y[] <- v$day else if(drop.year) {perm <- perm[perm != "y"] # drop yearsy[] <- paste(v[[perm[1]]], v[[perm[2]]], sep = sep)}else {perm <- perm[perm != "d"] # drop daysy[] <- paste(v[[perm[1]]], v[[perm[2]]], sep = sep)}}y[is.na(x)] <- NAy[x == Inf] <- "Inf"y[x == - Inf] <- "-Inf"att$format <- att$origin <- att$class <- NULLattributes(y) <- atty}print.dates <-function(x, digits = NULL, quote = FALSE, prefix = "", simplify, ...){if(!as.logical(length(x))) {cat("dates(0)\n")return(invisible(x))}if(missing(simplify) &&is.null(simplify <- getOption("chron.simplify")))simplify <- FALSEprint.default(format.dates(x, simplify = simplify), quote = quote)invisible(x)}seq.dates <- function(from, to, by = "days", length., ...){if(missing(from))stop("argument \"from\" must be specified")if(!inherits(from, "dates")) from <- chron(from[1])## the output will have same format and origin as "from"fmt <- attr(from, "format") # dates formatorg <- origin(from) # dates originif(is.numeric(by)) {cl <- class(from)from <- as.numeric(from)if(!missing(to)) {if(!inherits(to, "dates")) to <- chron(to[1])if(!is.null(to.org <- origin(to)) && any(to.org != org))origin(to) <- orgto <- as.numeric(to)}x <- seq.default(from, to, by)## preserve full chrons (i.e., don't round x)if(all(cl != "chron"))x <- round(x, 0)return(chron(x, format = fmt, origin = org))}if(!is.character(by) || length(by) != 1)stop("\"by\" must be a number or string (days, weeks, months, or years)")valid <- c("days", "weeks", "months", "years")if(!as.logical(i <- pmatch(by, valid, 0)))stop("\"by\" must be one of days, weeks, months, or years")by <- valid[i] # coerced "to" to a dates objectif(missing(to)) {if(missing(length.))stop("must specify \"length\" when \"to\" is missing")to <- from + (length. - 1) * c(1, 7, 31, 366)[i]## possibly BUGGY!!!}else {if(!missing(by) && !missing(length.))stop("Too many arguments")if(!inherits(to, "dates"))to <- chron(to)if(!missing(length.))by <- if(from < to) as.numeric(to - from)/(length. - 1) else 0}## make sure "from" and "to" have the same originif(!is.null(to.org <- origin(to)) && any(to.org != org))origin(to) <- orgif(from > to)stop("\"from\" must be a date before \"to\"")frm <- as.numeric(from)t0 <- as.numeric(to)frm.mdy <- month.day.year(frm, origin = org)## the idea is to generate all days between "form" and "to", subset## out the dates we need, and finally chron them.x <- seq.default(from = frm, to = t0)if(by == "days")return(chron(x, format = fmt, origin = org))if(by == "weeks") {mdy <- month.day.year(x, origin = org)mdy.dow <- day.of.week(mdy$month, mdy$day, mdy$year)frm.dow <- day.of.week(frm.mdy$month, frm.mdy$day, frm.mdy$year)x <- x[mdy.dow == frm.dow]return(chron(x, format = fmt, origin = org))}if(by == "months") {## be careful when "from" is in the tail of the month!nxt.day <- month.day.year(as.numeric(from + 1))$monthend.of.the.month <- frm.mdy$month != nxt.dayif(end.of.the.month) x <- c(x, x[length(x)] + 1)mdy <- month.day.year(x, origin = org)dys <- mdy$dayif(frm.mdy$day <= 28)x <- x[dys == frm.mdy$day]else if(end.of.the.month)x <- x[dys == 1] - 1else {## 29th or 30th of one of the 31-day monthsx1 <- x[dys == frm.mdy$day] # all but Feb!x2 <- x[mdy$month == 3 & dys == 1] - 1 # Febx <- sort(c(x1, x2))}## simple caseif(!missing(length.)) x <- x[seq(length = length.)]return(chron(x, format = fmt, origin = org))}if(by == "years") {## be careful when "from" is Feb 29 of a leap yearmdy <- month.day.year(x, org)if(leap.year(frm.mdy$year) && frm.mdy$day == 29)x <- x[mdy$day == 1 & mdy$month == 3] - 1elsex <- x[mdy$day == frm.mdy$day & mdy$month == frm.mdy$month]if(!missing(length.)) x <- x[seq(length = length.)]return(chron(x, format = fmt, origin = org))}}"trunc.dates" <-function(x){cl <- oldClass(x)class(x) <- NULLout <- NextMethod("trunc")class(out) <- cl[!as.logical(match(cl, "chron", 0))]out}"floor.dates" <-function(x){cl <- oldClass(x)class(x) <- NULLout <- NextMethod("floor")class(out) <- cl[!as.logical(match(cl, "chron", 0))]out}