如何仅用Busybox工具将带命名月份的日期转为Unix时间戳?
解决Busybox环境下带月份名称的日期转Unix时间戳问题
我之前在Busybox环境里也踩过这个坑——自带的date工具对带英文月份的日期格式完全不买账,连-D选项都没法用,手动写粗糙脚本实在太麻烦。这里分享两个更优雅的实现思路:
方案1:用Awk批量解析转换
如果需要处理大量日期,用Awk来映射月份、构造标准格式会更高效:
# 示例输入 input_date="Mon Jan 1 23:59:59 2018 GMT" # 转换逻辑 echo "$input_date" | awk ' BEGIN { # 初始化月份映射表 split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", mon_list, " ") for (i=1; i<=12; i++) { mon_num[mon_list[i]] = sprintf("%02d", i) } } { # 构造Busybox date能识别的ISO8601 GMT格式 printf "%s-%s-%sT%sZ\n", $4, mon_num[$2], sprintf("%02d", $3), $5 }' | TZ=GMT busybox date -d @- +%s
原理说明:
- 先通过Awk把英文月份转成两位数字;
- 把原日期拆分成
年-月-日T时间Z的ISO8601 GMT格式(带Z表示UTC/GMT); - 用
TZ=GMT确保date工具按GMT时区解析,最后输出Unix时间戳。
方案2:纯Shell脚本实现(无额外依赖)
如果环境里Awk也受限,用纯Shell的case语句就能搞定,依赖更少:
input="Mon Jan 1 23:59:59 2018 GMT" # 拆分日期字段 read -r _ mon day time year _ <<< "$input" # 月份名称转数字 case "$mon" in Jan) mon_num=01;; Feb) mon_num=02;; Mar) mon_num=03;; Apr) mon_num=04;; May) mon_num=05;; Jun) mon_num=06;; Jul) mon_num=07;; Aug) mon_num=08;; Sep) mon_num=09;; Oct) mon_num=10;; Nov) mon_num=11;; Dec) mon_num=12;; esac # 构造标准日期格式并转时间戳 TZ=GMT busybox date -d "${year}-${mon_num}-${day} ${time}" +%s
原理说明:
- 用
read拆分输入字符串的各个字段; - 通过
case语句手动映射月份名称到两位数字; - 构造
YYYY-MM-DD HH:MM:SS格式的日期,指定TZ=GMT解析后输出时间戳。
这两个方案都避开了Busyboxdate对英文月份的解析缺陷,而且比粗糙的脚本更易维护和扩展。
内容的提问来源于stack exchange,提问作者Nic
相关产品推荐
相关产品推荐

