Функция для получения предыдущего рабочего дня с учетом даты в Linux - PullRequest
0 голосов
/ 30 ноября 2018

Учитывая введенную дату, я хочу написать функцию bash, которая будет выводить предыдущий рабочий день.Под этим я подразумеваю предыдущий неделя день (с понедельника по пятницу);Мне не нужно принимать во внимание праздники.Так, например, с учетом «2 января 2018 года» результат должен быть «1 января 2018 года» (даже если это выходной день), а с учетом «1 января 2018 года» результат должен быть «29 декабря 2017 года» (потому что 30 и 31 декабря были суббота и воскресенье).Мне не нужен какой-то определенный формат;просто что-то удобочитаемое и приемлемое для date -d.

Я пробовал следующее, но, похоже, дата ввода не учитывается правильно:

function get_previous_busday()
{
    DAY_OF_WEEK=`$1 +%w`
    if [ $DAY_OF_WEEK -eq 0 ] ; then
        LOOKBACK=-2
    elif [ $DAY_OF_WEEK -eq 1 ] ; then
        LOOKBACK=-3
    else
        LOOKBACK=-1
    fi
    PREVDATE=date -d "$1 $LOOKBACK day"
}

Я хочуприменить его на сегодня:

PREVDATE=$(get_previous_busday $(date)) 
echo $PREVDATE

и на вчерашний день:

PREVDATE=$(get_previous_busday (date -d "$(date) -1 day")) 
echo $PREVDATE

Но это не работает:

main.sh: line 3: Fri: command not found 
main.sh: line 4: [: -eq: unary operator expected 
main.sh: line 6: [: -eq: unary operator expected 
main.sh: line 11: -d: command not found 
main.sh: command substitution: line 20: syntax error near unexpected token `date'
main.sh: command substitution: line 20: `get_previous_busday (date -d "$(date) -1 day"))'

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

Существует несколько способов получить смещение, необходимое для возврата к рабочему дню.

  1. Вы можете написать заявление о кейсе:

    case $dow in
        0|7)    backday=2;;   # For Sunday (either named 0 or 7) go back 2 days
        1)      backday=3;;   # For monday go back three (3) days.
        *)      backday=1;;   # For the rest, just one day.
    esac
    
  2. Вы можете использовать математику:

    backday=$(( ((dow%7)>1) ? 1 : (dow%7)+2 ))
    
  3. Или массив поиска:

    a=(0 1 2 3 4 5 6 7)
    b=(2 3 1 1 1 1 1 2)
    backday=${b[dow]}
    

Для любой альтернативы,Вы можете использовать эту (без обнаружения ошибок) функцию,
и некоторые тесты:

#!/bin/bash
get_previous_busday() {  dow=$(date -d "$*" '+%w')
                         backday=$(( ((dow%7)>1) ? 1 : (dow%7)+2 ))
                         prev_date="$(date -d "$* -$backday day")"
                         printf '%s\n' "$prev_date"
                      }

get_previous_busday "$(date)"
get_previous_busday $(date -d "-1 day")
get_previous_busday $(date -d "-2 day")
get_previous_busday $(date -d "-3 day")
get_previous_busday $(date -d "-4 day")

Напечатает:

Fri Nov 30 10:03:45 UTC 2018
Fri Nov 30 10:03:45 UTC 2018
Fri Nov 30 10:03:45 UTC 2018
Thu Nov 29 10:03:45 UTC 2018
Wed Nov 28 10:03:45 UTC 2018
0 голосов
/ 03 декабря 2018

Функция для выполнения того, что вы хотите:

get_previous_busday() {
        if [ "$1" = "" ]
        then
                printf 'Usage: get_previous_busday (base_date)\n' >&2
                return 1
        fi
        base_date="$1"
        if ! day_of_week="$(date -d "$base_date" +%u)"
        then
                printf 'Apparently "%s" was not a valid date.\n' "$base_date" >&2
                return 2
        fi
        case "$day_of_week" in
          (0|7)         # Sunday should be 7, but apparently some people
                        # expect it to be 0.
                offset=-2       # Subtract 2 from Sunday to get Friday.
                ;;
          (1)   offset=-3       # Subtract 3 from Monday to get Friday.
                ;;
          (*)   offset=-1       # For all other days, just go back one day.
        esac
        if ! prev_date="$(date -d "$base_date $offset day")"
        then
                printf 'Error calculating $(date -d "%s").\n' "$base_date $offset day"
                return 3
        fi
        printf '%s\n' "$prev_date"
}

Например,

$ get_previous_busday
Usage: get_previous_date (base_date)
$ get_previous_busday foo
date: invalid date ‘foo’
Apparently "foo" was not a valid date.
$ get_previous_busday today
Fri, Nov 30, 2018  1:52:15 AM
$ get_previous_busday "$(date)"
Fri, Nov 30, 2018  1:52:51 AM
$ PREVDATE=$(get_previous_busday $(date))
$ echo "$PREVDATE"
Fri, Nov 30, 2018 12:00:00 AM
$ get_previous_busday "$PREVDATE"
Thu, Nov 29, 2018 12:00:00 AM
$ PREVPREVDATE=$(get_previous_busday "$PREVDATE")
$ printf '%s\n' "$PREVPREVDATE"
Thu, Nov 29, 2018 12:00:00 AM
$ get_previous_busday "$PREVPREVDATE"
Wed, Nov 28, 2018 12:00:00 AM
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...