我使用RODBC库从数据库中提取信息。
library(RODBC)
stats <- function(user, pswd){
qry <- " select mydatetime from bar"
cn <- odbcConnect("A", uid=user, pwd= pswd)
rst <- sqlQuery(cn, qry, stringsAsFactors = F)
odbcClose(cn)
rm(list = c("cn", "qry"))
rst
}
my_list <- stats("a", "b")
我对产出感到困惑。这是一个POSIXct日期时间。当我my_list$mydatetime
列表时,它的显示方式如下:
[1] "2018-01-19 14:54:23 CET" "2018-01-19 14:53:22 CET" "2018-01-19 14:52:53 CET" "2018-01-19 14:51:50 CET"
[5] "2018-01-12 11:32:44 CET" "2018-01-12 11:32:02 CET" "2018-01-19 06:53:35 CET" "2018-01-19 06:52:06 CET"
[9] "2018-01-16 08:50:46 CET" "2018-01-16 08:49:59 CET" "2018-01-16 08:51:47 CET" "2018-01-15 05:31:53 CET"
注意CET
,这是正确的时区。当我运行attr(my_list$mydatetime,"tzone")
时,我得到了""
。
我的问题不是如何添加时区,而是,为什么在打印列表时会出现时区--这是令人困惑的,因为我假设它被当作CET日期时间处理,而实际上它似乎是一个日期时间而不是out时区?
发布于 2018-02-20 08:50:05
查看print.POSIXct
的源代码,我们可以看到以下内容:
print.POSIXct <- function (x, tz = "", usetz = TRUE, ...)
{
max.print <- getOption("max.print", 9999L)
FORM <- if (missing(tz))
function(z) format(x, usetz = usetz)
else function(z) format(x, tz = tz, usetz = usetz)
if (max.print < length(x)) {
print(FORM(x[seq_len(max.print)]), ...)
cat(" [ reached getOption(\"max.print\") -- omitted",
length(x) - max.print, "entries ]\n")
}
else print(if (length(x))
FORM(x)
else paste(class(x)[1L], "of length 0"), ...)
invisible(x)
}
这里的关键是,不管是否填充了"tzone“属性,x
都是使用format.POSIXct
格式化的。深入研究另一层,我们可以看到format.POSIXct
如下所示:
format.POSIXct <- function (x, format = "", tz = "", usetz = FALSE, ...)
{
if (!inherits(x, "POSIXct"))
stop("wrong class")
if (missing(tz) && !is.null(tzone <- attr(x, "tzone")))
tz <- tzone
structure(format.POSIXlt(as.POSIXlt(x, tz), format, usetz,
...), names = names(x))
}
同样,如果存在"tzone“属性,则通过。无论是否存在,POSIXct
对象在打印之前都会被胁迫到POSIXlt
对象中。现在,由于as.POSIXlt
直接对R解释器进行内部调用,所以我们无法轻松地调试源代码,因此我们陷入了困境。
但是,我们可以阅读POSIXlt
类(?POSIXlt
)的文档,并发现:
"POSIXlt“对象通常有一个属性"tzone",长度为3的字符向量从TZ环境变量中给出时区名称,以及基准时区和备用(夏时制)时区的名称。有时,这可能只是长度1,给出时区的名称。
因此,POSIXlt
对象确实有一个默认时区,取自系统宽TZ环境变量。此外,我们还宣读了下一段:
"POSIXct“对象也可能有一个属性"tzone",这是一个长度为1的字符向量。如果设置为非空值,它将决定如何将对象转换为"POSIXlt“类,特别是如何打印它。这通常是可取的,但是如果要在特定时区中指定对象,但要在当前时区中打印,则可能要删除"tzone“属性(例如,by c(x))。
因此,POSIXct
类中的"tzone“属性是告诉类在转换为POSIXlt
(例如用于打印)时使用什么时区,如果不希望它使用使用本地时区的默认行为。
https://stackoverflow.com/questions/48888931
复制