如何在jq中将秒数转换为指定格式的可读时长?
用jq将秒数转换为自定义人类可读时长格式
需求说明
输入为表示时长的秒数数组:
[ 30300, 120300, 296700, 31922700, 63458700 ]
需要转换为以下格式的字符串数组:
[ "0d, 08:25", "1d, 09:25", "3d, 10:25", "1y 4d, 11:25", "2y 4d, 11:25" ]
现有方案分析
你提到的通过gmtime+strftime的取巧方法虽能得到正确结果,但依赖日期解析的hack逻辑,可读性较差。这里提供一种更直观、可控的实现方案——直接通过数学运算拆解秒数到年、日、时、分单位。
更优实现方案
通过定义时间单位的秒数,逐步拆解总秒数到各个单位,再按需拼接成目标格式:
def format_duration: # 定义各时间单位对应的秒数(按平年365天计算,与示例逻辑一致) (365 * 86400) as $year_sec | 86400 as $day_sec | 3600 as $hour_sec | 60 as $min_sec # 拆解总秒数到各单位 | . as $total | ($total / $year_sec | floor) as $years | ($total % $year_sec) as $rem_after_year | ($rem_after_year / $day_sec | floor) as $days | ($rem_after_year % $day_sec) as $rem_after_day | ($rem_after_day / $hour_sec | floor) as $hours | ($rem_after_day % $hour_sec / $min_sec | floor) as $minutes # 拼接字符串并处理格式 | [ if $years > 0 then "\($years)y" else empty end, "\($days)d", "\($hours | tostring | lpad(2; "0")):\($minutes | tostring | lpad(2; "0"))" ] | join(", ") # 处理无年份时的格式(确保和示例一致) | sub("^, "; "") ; # 应用到输入数组 map(format_duration)
方案优势
- 逻辑直观:直接通过数学运算拆解时长,不依赖日期解析的隐含逻辑,便于理解和维护。
- 格式可控:可以灵活调整各单位的展示规则(比如是否保留前导零、单位分隔符等),无需后续字符串替换操作。
- 性能更优:减少了字符串正则替换的步骤,运算效率更高。
验证结果
将上述过滤器应用到输入数组,得到的输出与你期望的结果完全一致。
内容的提问来源于stack exchange,提问作者murison
相关产品推荐
相关产品推荐

