You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言中时间能否单独作为datetime类?POSIXct提取时间的困惑

关于POSIXct/POSIXt提取时间的疑问

我知道日期时间相关的问题一大堆,但还是得问——快抓狂了。我发现很多人都在尝试做这件事,但没意识到按最初的意图根本实现不了(不过可以用替换成相同年、月日的变通方法)。

为什么从POSIXct/POSIXt类向量中分离出时间会这么困难?

我的日期时间数据如下:

# 这些看起来没问题……所以不是EDT的问题
some_datetimes <- as.POSIXct(c("1961-07-16 05:00:00 EDT", "1961-07-16 05:00:00 EDT", "1961-07-16 17:00:00 EDT"))
class(some_datetimes)

some_datetimes <- as.POSIXct(c("1961-07-16 05:00:00", "1961-07-16 05:00:00", "1961-07-16 17:00:00"))
class(some_datetimes)

我想要提取时间,但希望它保持时间类(用于绘图/建模):

# 能否提取时间?
strptime(some_datetimes, format = "%H:%M:%S") # 返回NA
strptime(some_datetimes, format = "%T")       # 返回NA
strftime(some_datetimes, format = "%H:%M:%S") # 返回字符型
strftime(some_datetimes, format = "%T")       # 返回字符型
format(some_datetimes, format = "%H:%M:%S")   # 返回字符值
format(some_datetimes, format = "%T")         # 返回字符值

时间能否单独存在且仍为POSIXct类?

如果不能,为什么要这样设计?


核心原因:POSIXct的本质是带时区的时间戳

POSIXct类型本质是从1970-01-01 00:00:00 UTC开始计算的秒数,它必须绑定具体的日期和时区信息,不存在“只有时间没有日期”的POSIXct对象——这是设计上的限制,因为POSIX标准本身就是用来表示具体的时间点,而非一天内的时段。

可行的变通方案

如果你需要用于绘图或建模的“时间类”数据,有两种常用方法:

1. 绑定虚拟日期的POSIXct

把所有时间都绑定到同一个固定日期(比如1970-01-01),这样得到的POSIXct对象仅在时间部分有差异,完全满足绘图/建模需求:

# 提取时间字符串后拼接固定日期
time_only <- as.POSIXct(paste("1970-01-01", strftime(some_datetimes, "%H:%M:%S")))

# 查看结果
time_only
# [1] "1970-01-01 05:00:00 UTC" "1970-01-01 05:00:00 UTC" "1970-01-01 17:00:00 UTC"
class(time_only)
# [1] "POSIXct" "POSIXt"

2. 使用专门的时间类型(hms包)

如果不想依赖日期,可以用hms包提供的hms类型,它专门存储一天内的时间,支持向量运算和ggplot2绘图:

install.packages("hms")
library(hms)

# 提取时间转为hms类型
time_hms <- as_hms(some_datetimes)

# 查看结果
time_hms
# 05:00:00
# 05:00:00
# 17:00:00
class(time_hms)
# [1] "hms"      "difftime"

为什么strptime会返回NA?

strptime是用来解析字符型数据为POSIXlt的函数,你传入的是已经解析好的POSIXct对象,它无法识别,所以返回NA。如果要从POSIXct提取时间,必须先用strftime转成字符型,再处理。


内容的提问来源于stack exchange,提问作者Adam Kemberling

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:42:52