在R中将lubridate生成的UTC时区日期时间存入向量时为何时区会变更?
为什么用
c()存储lubridate的UTC时间会变成本地时区? 这个问题其实和R处理日期时间对象的逻辑以及c()函数的行为直接相关,我来给你拆解清楚:
首先,lubridate::now(tz = "UTC")返回的是一个带时区属性的POSIXct对象——POSIXct本质是把时间存储为自1970-01-01 UTC以来的秒数(数值型),同时附带一个tzone属性标记时区为UTC。当你直接打印它时,R会依据这个tzone属性,以UTC时区格式化显示数值对应的时间点。
但当你用c()把这个对象存入向量时,关键问题出现了:c()函数在处理单个POSIXct元素时,会剥离掉它的tzone属性。具体来说,c()会提取POSIXct的数值部分,再重新包装成一个新的POSIXct对象,但这个新对象丢失了时区标记。
R对于没有tzone属性的POSIXct对象,会默认使用系统本地时区(也就是你所在的东部时区EDT)来格式化显示时间。这里要注意:时间戳的核心数值(秒数)其实没有改变——你看到的2018-05-25 16:11:16 EDT和原来的2018-05-25 20:11:16 UTC是同一个时间点,只是显示的时区不同而已。
怎么避免这个问题?
如果你想保留时区,不要用c()来创建单个元素的向量,试试这两种方式:
# 方法1:直接赋值(最简洁) utc_time <- lubridate::now(tz = "UTC") # 方法2:预定义带时区的向量(适合批量场景) utc_vec <- vector("POSIXct", length = 1) attr(utc_vec, "tzone") <- "UTC" utc_vec[1] <- lubridate::now(tz = "UTC") # 验证结果,时区依然是UTC utc_vec #> "2018-05-25 20:11:16 UTC"
如果要组合多个日期时间对象,只要确保所有元素都有相同的时区,c()就会保留这个时区属性:
time1 <- lubridate::now(tz = "UTC") time2 <- lubridate::now(tz = "UTC") c(time1, time2) # 输出依然是UTC时区的时间
内容的提问来源于stack exchange,提问作者David Rubinger
相关产品推荐
相关产品推荐

