在 BSD 下解析任意自然语言日期

Gus*_*uss 3 freebsd date

我正在使用 GNU date 命令来解析任意自然语言日期 - 例如检测某个纪元时间戳是否来自上周,我可以这样做:

if [ "$timestamp" -lt "$(date +"%s" -d "last sunday")" ]; then ...
Run Code Online (Sandbox Code Playgroud)

现在,当我尝试将我的脚本移植到 FreeBSD 时,我如何实现相同的功能?man date没有表现出任何承诺,除非我错过了一些明显的东西。

Sté*_*las 5

FreeBSDdate上有许多命令使用与 GNU 相同的 API来输入用户的自然语言日期。我刚刚发现了一个可以被欺骗将该日期转换为 Unix 纪元时间的方法:

/usr/sbin/fifolog_reader -B 'last sunday' /dev/null 2>&1 |
  sed 's/^From[[:blank:]]*\([0-9]*\).*/\1/p'
Run Code Online (Sandbox Code Playgroud)

(请注意,至少在我尝试过的 FreeBSD 9.1-RELEASE-p2 上,它似乎只有在您处于 UTC 时区时才能可靠地工作,并且它识别的日期规范不一定与 GNU 日期识别的相同) .

请注意,某些 shell 内置了该功能。

ksh93

if (( timestamp < $(printf '%(%s)T' 'last sunday') )); then
Run Code Online (Sandbox Code Playgroud)

zsh

autoload calendar_scandate
calendar_scandate 'last sun'
if (( timestamp < REPLY)); then...
Run Code Online (Sandbox Code Playgroud)

或者你可以使用perlDate::Manipif 安装:

last_sun=$(perl -MDate::Manip -e 'print UnixDate("last sunday","%s")')
if [ "$timestamp" -lt "$last_sun" ]; then...
Run Code Online (Sandbox Code Playgroud)

或者:

if perl -MDate::Manip -e 'exit 1 unless $ARGV[0] < UnixDate("last sunday","%s")
    ' "$timestamp"; then....
Run Code Online (Sandbox Code Playgroud)

如果目的是检查文件时间戳,请注意 FreeBSDfind支持:

find file -prune -newermt 'last sunday'
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果您想要本周开始的时间(从周日开始的几周),您可以执行以下操作:

week_start=$(($(date '+%s - 86400*%w - 3600*%H - 60*%M - %S')))
Run Code Online (Sandbox Code Playgroud)

这应该适用于 GNU 和 FreeBSD(或任何%s受支持的系统)。

在夏令时的时区中,在夏令时切换前后将关闭一个小时。