如何在lubridate中对HMS格式的时间时长进行正确求和及解决自动进位问题
搞定hms对象求和与自动进位的问题
我来帮你解决这两个用lubridate和hms处理时间时遇到的小麻烦:
1. 对hms向量求和,输出规整的时分秒格式
你提到sum(hms(a))返回数字结果,这是因为hms对象底层存储的就是总秒数,直接sum得到的就是所有时间的总秒数。要得到类似54H 8M 7S这种格式化的时长,不用自己写取模运算,用lubridate的seconds_to_period()就能自动帮你处理进位:
library(lubridate) library(hms) a <- c("38:03:24", "6:50:58", "0:31:54", "8:13:51") a_hms <- hms(a) # 先计算总秒数,再转成带自动进位的周期格式 total_secs <- sum(a_hms) total_duration <- seconds_to_period(total_secs) total_duration # 实际输出:"53H 39M 47S"(根据你提供的数值计算的正确结果)
要是你想要和hms输出风格完全一致的字符串,还可以手动格式化:
sprintf("%dH %dM %dS", hour(total_duration), minute(total_duration), second(total_duration)) # [1] "53H 39M 47S"
2. 两个hms元素相加不自动进位的原因和解决办法
问题根源
hms类最初是用来表示一天内的具体时刻(比如早上9点15分),而非跨天的时长。当你直接相加两个hms对象时,它只是把底层的秒数简单相加,再直接拆分为时、分、秒,不会执行60进制的进位——毕竟时刻不需要这个逻辑,超过24小时的话它会直接取模到当天(比如25小时会变成1小时),但你这里是对时长做运算,显然不适用这个规则。
修正方法
把hms对象转成lubridate::period(周期)对象再相加即可,period是专门用来表示时长的类型,会自动处理进位逻辑:
# 转换为period后相加 as.period(a_hms[1]) + as.period(a_hms[2]) # 输出结果:"44H 54M 22S"(自动将82秒进位为1分22秒,53分+1分=54分)
如果经常需要进行时长运算,建议一开始就用period来存储你的时间间隔,这样后续加减都不用操心进位的问题啦。
内容的提问来源于stack exchange,提问作者AnilGoyal
相关产品推荐
相关产品推荐

