为了简化问题,假设我有变量:(
dat="10152015"
代表 2015 年 10 月 15 日)结果dat
应该是10142015
请注意,我没有使用今天的日期。
我遇到的问题是想办法将日期减少 1 天。我可以只减少第四位数字,但这是一个日历。
我目前的想法是将其转换为unix理解的格式(无论是什么),然后尝试从那里开始工作,然后将答案转换回来
答案1
需要 GNU 日期:
dat="10152015"
date -d "${dat:4}${dat:0:4} yesterday" +%m%d%Y
YYYYMMDD
是 ISO 9601 日期格式,MMDDYYYY
只需使用普通子字符串扩展交换两半即可将打包的美国格式转换为该格式。
这需要 gnu date,我不认为其他版本的 date 支持显示非当前时间。
答案2
首先用于sed
将您提供的格式 10152015 转换为该命令mm/dd/yyyy
的 GNU 实现date
及其-d
选项可以理解的格式。这是通过回显sed
插入斜杠的原始日期来完成的/
。此重新格式化的日期值存储在D
.接下来我们调用date
指令打印输出格式“mmddyyyy”,并告诉它打印yesterday
使用的日期$D
作为当前日期。
#!/bin/sh
D=$(echo "${1-10152015}" | sed 's,^\(..\)\(..\)\(....\)$,\1/\2/\3,')
date +%m%d%Y -d"$D yesterday"
答案3
bash
不是日期计算的最佳 shell,因为它的日期操作功能非常有限。
和zsh
:
zmodload zsh/datetime
d=03012012
strftime -rs d %m%d%Y%H ${d}12
strftime %m%d%Y $((d-86400))
和ksh93
:
d=03012012
printf "%(%m%d%Y)T\n" "${d:4}${d:0:4} yesterday"
使用bash
,您要么必须手动进行计算,要么依赖perl
该实用程序的某些 GNU 或 FreeBSD 扩展date
。
答案4
注意:以下内容假设来自 GNU coreutils 的 GNU 日期。如果您有不同的实用程序,请适应您的系统日期date
。
您的想法是正确的,您需要转换为自纪元(1970 年 1 月 1 日 00:00:00)以来的秒数。
GNU 日期在其解释的日期格式方面相当灵活,但 MMDDYYYY 不是其中之一。幸运的是,您可以使用 sed 重新格式化日期(转换为 YYYY-MM-DD 格式),然后再将其提供给date -d
dat="10152015"
secs=$(date +%s -d $(echo "$dat" | sed -e 's/\(..\)\(..\)\(....\)/\3-\1-\2/'))
newsecs=$((secs - 86400))
date -d "@$newsecs"