如何将a.m./p.m.格式转为hms?合并日期与班次起止时间方法
解决方法
核心问题是%p格式符默认只识别AM/PM,不支持a.m./p.m.格式,所以需要先预处理时间字符串,再合并解析。以下是几种可行方案:
方案1:替换时间格式后用基础函数解析
先把a.m./p.m.替换为AM/PM,再合并日期与时间字符串,最后用strptime解析:
# 假设你的数据集名为df,shift_date格式如"2024-05-20",shift_start如"9:30 a.m." # 替换时间字符串中的a.m./p.m. df$shift_start_clean <- gsub("a\\.m\\.", "AM", df$shift_start) df$shift_start_clean <- gsub("p\\.m\\.", "PM", df$shift_start_clean) # 合并日期与时间 df$shift_start_combined <- paste(df$shift_date, df$shift_start_clean) # 解析为datetime对象 df$shift_start_datetime <- strptime(df$shift_start_combined, "%Y-%m-%d %I:%M %p") # 对shift_end执行同样操作 df$shift_end_clean <- gsub("a\\.m\\.", "AM", df$shift_end) df$shift_end_clean <- gsub("p\\.m\\.", "PM", df$shift_end_clean) df$shift_end_combined <- paste(df$shift_date, df$shift_end_clean) df$shift_end_datetime <- strptime(df$shift_end_combined, "%Y-%m-%d %I:%M %p")
方案2:用lubridate的灵活解析功能
lubridate的parse_date_time函数支持自定义格式规则,也能处理去掉点后的am/pm格式:
library(lubridate) # 去掉时间字符串中的点,将a.m.转为am,p.m.转为pm df$shift_start_clean <- gsub("\\.", "", df$shift_start) df$shift_end_clean <- gsub("\\.", "", df$shift_end) # 合并日期与时间后解析(根据你的shift_date格式调整orders参数) df$shift_start_datetime <- parse_date_time( paste(df$shift_date, df$shift_start_clean), orders = c("ymd hm p", "dmy hm p") ) df$shift_end_datetime <- parse_date_time( paste(df$shift_date, df$shift_end_clean), orders = c("ymd hm p", "dmy hm p") )
方案3:用anytime自动识别格式
anytime包能自动识别绝大多数日期时间格式,包括a.m./p.m.,无需手动替换:
library(anytime) # 直接合并日期与时间后解析 df$shift_start_datetime <- anytime(paste(df$shift_date, df$shift_start)) df$shift_end_datetime <- anytime(paste(df$shift_date, df$shift_end))
注意事项
- 如果
shift_date的格式不是标准的YYYY-MM-DD,需要在解析时指定对应格式(比如%d/%m/%Y),或者先通过lubridate的dmy/mdy等函数将shift_date转为日期对象,再与时间部分相加。 - 验证解析结果时,可以用
class(df$shift_start_datetime)检查是否为POSIXlt或POSIXct类型,确保后续对比操作正常。
内容的提问来源于stack exchange,提问作者Abhijay Pandita
相关产品推荐
相关产品推荐

