R中fread生成的POSIXct类型时间时区转换失效问题咨询
问题解答
1. fread自动识别时间戳为POSIXct类型的原理
data.table的fread内置了智能列类型推断规则:
- 读取文件时默认扫描前1000行数据,逐列判断值的格式特征
- 若某一列的所有扫描值都匹配
YYYY-MM-DD HH:MM:SS这类标准时间格式,就会自动将该列解析为POSIXct类型,默认采用UTC作为时区。
2. POSIXct类型时区转换的正确方法
首先明确:POSIXct类型对象不需要先转字符再修改时区,你之前直接调用as.POSIXct不生效的原因是:对于已经是POSIXct类型的输入,as.POSIXct默认会忽略tz参数,保留原有对象的时区属性。
根据实际需求,有两类常用处理方式:
需求1:将UTC时区的时间换算为对应Asia/Kolkata时区的时间(时间戳绝对值不变,仅转换时区显示)
这是最常用的时区转换场景,有两种实现方法:
- 直接修改POSIXct对象的tzone属性:
attr(dt$creation_time, "tzone") <- "Asia/Kolkata" - 使用lubridate包的
with_tz函数,语法更简洁:library(lubridate) dt[, creation_time := with_tz(creation_time, tz = "Asia/Kolkata")]
需求2:保留时间的字面数值,将其直接定义为Asia/Kolkata时区的时间(不需要时差换算)
就是你先转字符再转换的效果,相当于丢弃原有UTC时区属性,将「2021-08-09 18:55:43」这个字面值直接当成Asia/Kolkata时区的时间,这种场景下你的写法是可行的,也可以用lubridate::force_tz实现相同效果,不需要转字符:
library(lubridate) dt[, creation_time := force_tz(creation_time, tz = "Asia/Kolkata")]
内容的提问来源于stack exchange,提问作者leoOrion
相关产品推荐
相关产品推荐

