如何无需拆分字符串将含百分秒的字符型时间戳转换为带百分秒的datetime格式?
如何无需拆分字符串将含百分秒的字符型时间戳转换为带百分秒的datetime格式?
看起来你遇到了R中解析带百分秒时间戳的常见坑,其实完全不用拆分字符串,只要调整格式字符串和显示选项就能完美解决,我来一步步给你理清楚:
1. 基础R(strptime/as.POSIXct)的正确解法
你的问题出在两个细节上:一是没明确指定秒小数部分的位数,二是R默认不会显示小数秒。只要补上这两点,基础R函数就能正常工作:
- 首先设置
options(digits.secs = 2),让R显示两位小数的秒部分; - 格式字符串改用
%d%b%Y:%H:%M:%S.%OS2,其中%OS2专门用来解析两位小数的秒(%OS后面跟数字n就表示解析n位小数)。
代码示例:
# 开启两位小数秒的显示 options(digits.secs = 2) # 用strptime转换 strptime("09JUN2022:00:00:00.04", "%d%b%Y:%H:%M:%S.%OS2", tz = "UTC") # 输出:[1] "2022-06-09 00:00:00.04 UTC" # 用as.POSIXct转换(效果完全一致) as.POSIXct("09JUN2022:00:00:00.04", format = "%d%b%Y:%H:%M:%S.%OS2", tz = "UTC") # 输出:[1] "2022-06-09 00:00:00.04 UTC"
为什么之前的尝试失败?
- 只用
%OS而不指定位数时,R会根据系统默认规则解析,容易出现误判(比如你之前得到的00:00:04就是解析逻辑出错的结果); - 没设置
digits.secs的话,哪怕R已经正确存储了小数秒,默认打印时也会把这部分隐藏起来。
2. lubridate的简化写法(无需拆分字符串)
你之前用dmy()+hms()拆分字符串完全没必要,lubridate提供了dmy_hms()函数,可以直接解析这种“日期:时间”格式的字符串:
library(lubridate) options(digits.secs = 2) # 直接解析完整时间戳 dmy_hms("09JUN2022:00:00:00.04", tz = "UTC") # 输出:[1] "2022-06-09 00:00:00.04 UTC"
关于你遇到的0.01精度误差
这是浮点数存储的正常现象:像0.04这类十进制小数,转换成二进制浮点数时会有微小的精度损失,显示时可能会变成0.03,但实际存储的值非常接近0.04,对后续计算几乎没有影响。如果实在在意,可以用round()函数修正:
ts <- dmy_hms("09JUN2022:00:00:00.04", tz = "UTC") round(ts, digits = 2)
备注:内容来源于stack exchange,提问作者Deuian
相关产品推荐
相关产品推荐

