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

在R中将无前置零的H/M/S格式转换为HH:MM:SS或时间对象

时间格式转换与解析问题

问题背景

数据被从标准的HH:MM:SS格式改成了无前置零的H/M/S格式:

  • 示例1:10:32:20 → 10H 32M 20S
  • 示例2:7:30:04 → 7H 30M 4S

想搞清楚这种格式是不是某个R包的标准格式,同时需要将其转换回HH:MM:SS格式,或者直接解析为时间对象。

最初只注意到秒数缺失前置零,写了如下代码,但处理不全面:

# turn e.g. 10H 12M 30S -> 10:12:30
df$Time = gsub(" ", "", c(df$Time))
df$Time = gsub("[^0-9]", ":", c(df$Time))
df$Time = gsub("::", ":", c(df$Time))
df$Time = substring(df$Time,1,nchar(df$Time) - 1)

for (i in seq_along(df$Time)) {
  if (nchar(df$Time[i]) == 7) {
    gsub("([0-9]*$)", paste(0, str_sub(df$Time[i], start=7), sep=""), df$Time[i])
  }
}

解决方案

方法1:正则拆分+补零转换为HH:MM:SS

用正则表达式提取时、分、秒的数值,再通过sprintf统一补零到两位,最后拼接成目标格式:

library(stringr)

# 定义转换函数
convert_time <- function(time_str) {
  # 提取时、分、秒的数字
  hours <- str_extract(time_str, "\\d+(?=H)")
  mins <- str_extract(time_str, "\\d+(?=M)")
  secs <- str_extract(time_str, "\\d+(?=S)")
  
  # 补零并拼接
  sprintf("%02d:%02d:%02d", as.integer(hours), as.integer(mins), as.integer(secs))
}

# 测试示例
test_times <- c("10H 32M 20S", "7H 30M 4S", "1H 2M 3S")
sapply(test_times, convert_time)
# 输出:
# "10H 32M 20S" "7H 30M 4S"   "1H 2M 3S" 
# "10:32:20"    "07:30:04"    "01:02:03"

方法2:直接解析为时间对象(用lubridate包)

如果不需要转成字符串格式,而是要解析为时间间隔对象,可以用lubridate包的时间组件函数:

library(lubridate)
library(stringr)

# 解析为Period对象(表示时间间隔)
parse_time_obj <- function(time_str) {
  hours <- as.integer(str_extract(time_str, "\\d+(?=H)"))
  mins <- as.integer(str_extract(time_str, "\\d+(?=M)"))
  secs <- as.integer(str_extract(time_str, "\\d+(?=S)"))
  hours(hours) + minutes(mins) + seconds(secs)
}

# 测试
parse_time_obj("7H 30M 4S")
# 输出:[1] "7H 30M 4S"

关于格式疑问:目前没有广泛使用的R包将这种格式作为时间存储的标准格式,更可能是人为自定义的显示格式,比如为了节省字符长度或适配特定场景的可读性需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 10:45:48