例如,给定日期为2016-12-31',n为2,预期输出为2016-12-29'。
我调查date
命令并且从当前日期开始n天前很容易:
date -d "2 days ago" +%Y-%m-%d
答案 0 :(得分:9)
只需提及您想要提取两天的日期:
$ date -d "2016-12-31 2 days ago" +%Y-%m-%d
2016-12-29
或者语法更好一点:
$ date -d "2016-12-31 -2 days" +%Y-%m-%d
2016-12-29
答案 1 :(得分:1)
如果你没有GNU日期,也许你有BSD date。在这种情况下,您可以这样做:
date -jf %s $(( $(date +%s) - 86400 * 2 ))
请注意,这不是POSIX,也不是GNU。
这告诉BSD日期不要更改时钟(-j
)并将输入作为UNIX time(1970/01/01 00:00:00 UTC之后的秒,-f %s
)。提供的时间是当前时间的数学替换($(date +%s)
,使用相同的格式但作为输出)减去一天中的秒数(86400)乘以2。
在过去,我编写的代码用于查找GNU,然后故障转移到BSD:
# Usage: _epoch2datefmt UNIX_TIME [+FORMAT]
if date -d @1484850180 +%s >/dev/null 2>&1
then _epoch2datefmt() { date -d @"$@"; } # GNU
else _epoch2datefmt() { date -jf %s "$@"; } # BSD
fi
对于这个问题,我们还需要走另一个方向。 BSD日期也需要格式:
# Usage: _date2epoch YYYY-MM-DD [INPUT_FORMAT]
if date -d 2017-01-19 +%s >/dev/null 2>&1
then _yyyymmdd2epoch() { date -d "$1" +%s; } # GNU
else _yyyymmdd2epoch() { date -jf "$2" "$1" +%s; } # BSD
fi
以下是如何将这些组合在一起,以便在给定日期前两天使用GNU或BSD:
_epoch2datefmt $(( $(_date2epoch 2016-12-31 %Y-%m-%d) - 2 * 86400 )) +%Y-%m-%d
从内到外,这将2016-12-31转换为UNIX时间,减去两天(一天中有86400秒),然后将生成的UNIX时间(答案)传递回YYYY-MM -DD格式。
如果你想在一个函数中使用它,可能是:
# Usage: _date_helper INPUT_FORMAT DATE [+OUTPUT_FORMAT]
if date -d@1484850180 +%s >/dev/null 2>&1
then _date_helper() { local A=; [ "$1" = %s ] && A=@; shift; date -d "$A$@"; }
else _date_helper() { date -jf "$@"; }
fi
(由于GNU的%s
需要一个前导date -d
,因此我必须处理输入UNIX时间(由第一个参数@
表示)有点棘手。这样可以节省如果需要,在$A
中填写前缀,清除格式(GNU是智能的,否则不需要它),然后将其余部分传递给GNU date
命令.BSD版本应该是不言自明的。 )
以下是如何使用此功能运行它以“2016-12-31之前两天”:
_date_helper %s $(( $(_date_helper %Y-%m-%d 2016-12-31 +%s) - 86400 * 2)) +%Y-%m-%d