Получить дату следующей субботы из заданной даты

Существует две вещи, связанные с выполнением этого:

  1. Как получить электронную почту к системе
  2. обработайте электронную почту для добавления информации в файл

Первое, которое можно решить при наличии почты быть отправленными на сервер непосредственно, но если сервер не онлайн все время (расположен дома), вероятно, лучше отправить электронные письма в некоторый Google, или Yahoo считают и выбирают их оттуда. Можно сделать это с fetchmail, и поставлять почту локально пользователю list.

Для второй части можно использовать procmail с определенными правилами для пользователя в ~/.procmailrc. Курьеру местной почты нужно сказать использовать procmail например, в postfix Вы добавляете:

mailbox_command = procmail -a "$EXTENSION"

к Вашему /etc/postfix/main.cf файл.

В файле ~list/.procmailrc можно указать правила о том, что сделать с почтой (все письма, прибывающие там или те с определенными характеристиками (предмет, от адреса, и т.д.)). procmail имеет несколько полезных сборок в действиях, и если они не удовлетворяют, что можно передать почту по каналу в программу, чтобы сделать что-то определенное, которое это не может сделать.

4
11.08.2015, 02:00
6 ответов

С ksh93 :

$ LC_ALL=C ksh93 -c 'printf "%(%c)T\n" "30-Aug-2015 Saturday"'
Sat Sep  5 00:00:00 2015

Обратите внимание, что если дата - суббота, то она вернется в тот же день, если вы хотите в следующую субботу сделайте это:

LC_ALL=C printf "%(%c)T\n" "30-Aug-2015 tomorrow Saturday"

Замените % c на требуемую спецификацию strftime :

$ LC_ALL=C printf "%(%d-%b-%Y)T\n" "03-Jan-2015 tomorrow saturday"
10-Jan-2015

На GNU date :

$ d=03-JAN-2015
$ LC_ALL=C date -d "$d +1 week -$(date -d "$d +1 day" +%w) day" '+%d-%^b-%Y'
10-JAN-2015
3
27.01.2020, 20:49

Из того, что вы пробовали, я предполагаю, что вам нужна единственная команда. Мне не удалось его найти, но я адаптировал этот ответ , чтобы делать то, что вы хотите:

# Assume that date1 is already set to "30-AUG-2015"
try_date="$date1"
while [ "$(date --date="$try_date" +"%A")" != Saturday ]
do
    try_date=$(date --date="$try_date + 1 day" +"%d-%b-%Y")
done
date2="$try_date"
echo "$date2"

Вывод:

05-Sep-2015

Вы можете изменить строку , а на либо

  • while ["$ (date --date =" $ try_date "+"% a ")"! = Sat]
    или
  • while ["$ (date --date =" $ try_date " + «% 5») «! = 6]
    (используйте 1 для понедельника… 7 для воскресенья)

Если $ date1 равно« 29 августа 2015 года »(суббота), тогда $ date2 будет« 29 августа 2015 года »(то есть в тот же день). Если вы все же хотите получить 5 сентября 2015 г. для этого ввода (т. Е. В следующую субботу после $ date1 ), измените первую строку {{ 1}} по try_date = $ (date --date = "$ date1 + 1 day" + "% d-% b-% Y") .

Если вы действительно хотите, чтобы месяц был написан заглавными буквами (например, «SEP»), используйте tr .

1
27.01.2020, 20:49

Я настоятельно рекомендую dateutils для подобных вещей. ( yum install dateutils в Fedora 21+ или CentOS / RHEL 7 с EPEL.) Затем просто выполните:

dateround today sunday

Вы можете использовать «сегодня» или заменить фактическую дату:

$ dateround 2015-08-30 saturday
2015-09-05

Если вам нужно дата ввода должна быть в определенном формате, например 30-AUG-2015, вы можете использовать -i или - input-format , например:

$ dateround -i '%d-%b-%Y'30-AUG-2015 saturday
2015-09-05
5
27.01.2020, 20:49

Мой лучший ответ на этот вопрос:

IFS="#"; ((
for s_date in $(echo ${date1}' +'{1..7}' days#'); do 
date -d "${s_date}";
done
) | grep Sat
) | xargs -I {} date +%d-%b-%Y -d "{}"

Выход:

05-Sep-2015

Это создает список из #разделенных строк, таких как:

"30-AUG-2015 +1 days# 30-AUG-2015 +2 days# 30-AUG-2015 +3 days#..."

Затем этот список зацикливается и передается в date, где я могу grepуказать день, который я ищу, (, например. Сб ). Наконец, я могу использовать xargsдля преобразования вывода в формат, который вы ищете. Для удобства код можно поместить в одну строку.

0
27.01.2020, 20:49

Однострочное решение -для любого дня недели без циклов

MON=1
TUE=2
WED=3
THU=4
FRI=5
SAT=6
SUN=7

echo "Today "          && date
echo "Next Monday "    && date -d "+ $(( ( (6 + $MON - $(date +%u)) % 7) + 1 )) days"
echo "Next Tuesday "   && date -d "+ $(( ( (6 + $TUE - $(date +%u)) % 7) + 1 )) days"
echo "Next Wednesday " && date -d "+ $(( ( (6 + $WED - $(date +%u)) % 7) + 1 )) days"
echo "Next Thursday "  && date -d "+ $(( ( (6 + $THU - $(date +%u)) % 7) + 1 )) days"
echo "Next Friday "    && date -d "+ $(( ( (6 + $FRI - $(date +%u)) % 7) + 1 )) days"
echo "Next Saturday "  && date -d "+ $(( ( (6 + $SAT - $(date +%u)) % 7) + 1 )) days"
echo "Next Sunday "    && date -d "+ $(( ( (6 + $SUN - $(date +%u)) % 7) + 1 )) days"

Выход

Today
Thu, Nov 12, 2020 10:24:38 PM
Next Monday
Mon, Nov 16, 2020 10:24:39 PM
Next Tuesday
Tue, Nov 17, 2020 10:24:40 PM
Next Wednesday
Wed, Nov 18, 2020 10:24:40 PM
Next Thursday
Thu, Nov 19, 2020 10:24:41 PM
Next Friday
Fri, Nov 13, 2020 10:24:42 PM
Next Saturday
Sat, Nov 14, 2020 10:24:42 PM
Next Sunday
Sun, Nov 15, 2020 10:24:43 PM

Пояснение

Идея состоит в том, чтобы рассчитать количество дней до следующего дня недели и добавить это число к текущей дате. Возьмем в качестве примера субботу.

  • В понедельник добавить 5 дней
  • ...
  • В пятницу добавить 1 день
  • В субботу добавить 7 дней
  • В воскресенье добавить 6 дней

Таким образом, первая итерация алгоритма выглядит следующим образом: берем текущий день недели date +%u, берем mod 7и добавляем 1, потому что модуль основан на нуле:

( $(date +%u) % 7) + 1

Однако он не принимает во внимание, что наша последовательность дней для добавления является убывающей (5,4,3,2,1,7,6 ). Для этого нам нужно вычесть текущий день недели из 7, затем взять по модулю и прибавить1:

( (7 - $(date +%u)) % 7) + 1

Итак, мы получили рабочий пример для понедельника(7 == 6 + $MON). Чтобы он искал любую неделю дня, мы должны переписать -как

( (6 + <DAY> - $(date +%u)) % 7) + 1

где <DAY>должна быть любой из переменных выше($MON...$SUN)

Модификация для Alpine Linux

Alpine Linux не поддерживает -d "+ 3 days", поэтому вы либо устанавливаете coreutils(apk add coreutils), чтобы заставить его работать, либо сами выполняете арифметические расчеты дней.

date -d "@$(($(date +%s) + 86400 * $(( ( (6 + $SAT - $(date +%u)) % 7) + 1 )) ))"

Пояснение

$(date +%s)выводит количество секунд, прошедших с... знаете ли! 86400количество секунд в день, date -d "@<number_of_seconds>"восстанавливает дату из измененного количества секунд.

Модификация для Mac OS

Работает как "Модификация для Alpine Linux" за исключением MacOS, вместо date -d "@<number_of_seconds>"пишется date -r "<number_of_seconds>", поэтому

date -r "$(($(date +%s) + 86400 * $(( ( (6 + $SAT - $(date +%u)) % 7) + 1 )) ))"

Дополнительные сведения см. в разделе «Модификация для Alpine Linux/Пояснение» выше.

3
13.11.2020, 02:51

Гораздо проще написать решение::

$ adate1="30-AUG-2015"

$ faketime "$adate1" date -d 'saturday' +'%d-%b-%Y'

05-Sep-2015

Конечно, нужно установить faketime.

1
05.10.2021, 17:41

Теги

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