从 lubridate 创建新的日期时间组件时,时区会丢失

Time zone gets lost with lubridate when creating a new datetime component from it

以下数据框来自dput。我在没有参数的情况下在数据时间上使用了 forced_tz。我住在 UTC+1 时区。

library(lubridate)
library(dplyr)

df <- structure(list(value = structure(c(1514967058, 1515148132, 1517472989, 1543844646, 1525085884, 1520584330, 1522838681, 1540379051, 1516707360, 1516705706), 
                                 class = c("POSIXct", "POSIXt"))), 
          .Names = "value", 
          row.names = c(NA, -10L), 
          class = c("tbl_df", "tbl", "data.frame"))


    tz(df$value)
[1] ""

df2 <- df %>% 
  mutate(year=year(value))


    > tz(df2$year)
[1] "UTC"

我也使用过 tz= "Europe/Paris",但是当我从日期时间(daymonth 等)中提取一些内容时,他们会失去时区并再次获得 UTC。是否可以设置一次时区然后转移到我创建的所有新日期时间组件?

问题是 year() 似乎 return 是 numeric,所以它不再是 date 对象。

这是 year() 的默认方法:

year.default <- function(x)
    as.POSIXlt(x, tz = tz(x))$year + 1900

因此,例如:

y <- as.POSIXlt("2018-01-03 09:10:58 CET", tz = Sys.timezone())$year + 1900
#y
#[1] 2018

请注意,我将当前的 tz 强制为 Sys.timezone()

但是:

class(y)
#[1] "numeric"

所以当你调用 tz(y) 时,因为它是数字,所以它没有 tz 属性,默认情况下它被赋予 "UTC".

# example:
# tz(123)
# [1] "UTC"

一个简单的解决办法是给自己设置时区:

attr(y, "tzone") <- Sys.timezone()
y
#[1] 2018
#attr(,"tzone")
#[1] "Europe/Berlin"

所以现在 tz 有效:

tz(y)
[1] "Europe/Berlin"

我不建议这样做,但您也可以修改 tz():

的默认方法
my_tz <- function(x) {
  tzone <- attr(x, "tzone")[[1]]
  if (is.null(tzone) && !is.POSIXt(x))
    return(Sys.timezone()) # original was "UTC"
  if (is.character(tzone) && nzchar(tzone))
    return(tzone)
  tzone <- attr(as.POSIXlt(x[1]), "tzone")[[1]]
  if (is.null(tzone))
    return(Sys.timezone()) # original was "UTC"
  tzone
}

my_tz(y)
#[1] "Europe/Berlin"

所以现在你有了 tz() 的 "custom" 版本,当输入的日期格式不正确时,它 return 就是当前时区。