Парсинг произвольных дат естественного языка под BSD

Эта ошибка теперь исправлена в bindfs версии 1.12.3.

Ответ Gilles объясняет ошибку великолепно.

3
05.08.2014, 18:08
3 ответа

Во FreeBSD есть ряд команд , которые используют тот же API, что и GNU дата для ввода дат на естественном языке от пользователя . Я только что нашел одну, которую можно обмануть, преобразовав эту дату во время эпохи Unix:

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

(обратите внимание, что, по крайней мере, на FreeBSD 9.1-RELEASE-p2, где я это примерял, она, кажется, работает надежно только в том случае, если вы находитесь в UTC-таймзоне, а распознаваемые ею спецификации дат не обязательно совпадают с распознаваемыми датами GNU).

Обратите внимание, что некоторые оболочки имеют такую возможность встроены.

ksh93:

if (( timestamp < $(printf '%(%s)T' 'last sunday') )); then

zsh:

autoload calendar_scandate
calendar_scandate 'last sun'
if (( timestamp < REPLY)); then...

Или вы можете использовать perl и Date::Manip, если установлено:

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

Или:

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

Если целью является проверка временных меток файлов, то обратите внимание, что FreeBSD находит поддержку :

find file -prune -newermt 'last sunday'

В этом самом случае, если вам нужно время начала этой недели (недели, начинающиеся в воскресенье), вы можете сделать:

week_start=$(($(date '+%s - 86400*%w - 3600*%H - 60*%M - %S')))

Это должно работать как в GNU, так и в FreeBSD (или в любой другой системе, где поддерживается %s).

В часовых поясах с летним временем, которые будут отключены на час вокруг переключателя с/на летнее время.

.
5
27.01.2020, 21:11

Вероятно, лучший способ обеспечить совместимость - это установить дату GNU в систему FreeBSD.

Вы можете установить пакет coreutils из коллекции портов FreeBSD. Это поместит команду даты GNU в /usr/local/bin/gdate.

.
2
27.01.2020, 21:11

Хотя это может быть применимо не ко всем операциям, которые могут быть легко выражены естественным языком, оператор date во FreeBSD имеет оператор -v, который позволяет устанавливать как произвольные, так и относительные значения в отдельные поля даты, и это можно повторить по мере необходимости для получения большинства эффектов.

Например, чтобы получить "последнее воскресенье", можно применить "обнулить все временные поля", а затем "обнулить все временные поля", как например:

date -v0S -v0M -v0H -v0w

, так что бэш-спикер для "дайте мне секунды с начала последнего воскресенья, независимо от того, работаете ли вы под Linux или BSD", будет выглядеть следующим образом:

last_sunday_start() {
    if [ "$(uname)" = "Linux" ]; then
        date +"%s" -d "next sunday -1 week"
    else
        date -v0S -v0M -v0H -v0w +"%s"
    fi
}

Обратите внимание, что пример GNU date в вопросе неверен, если вы хотите получить "последний раз, когда произошло воскресенье 00:00:00" - он вернет начало предыдущего воскресенья, когда звонят в течение воскресенья. В приведенном выше коде также исправлена спецификация даты GNU для этого.

.
1
27.01.2020, 21:11

Теги

Похожие вопросы