Укажите согласованные границы недели, используя дату

Мне нужно запустить определенную программу, передав ей границы недели. (Я использую CentOS release 6.4 , так что решение gnu date bash / gnu date отлично). Я пробовал это вчера (в понедельник):

 for ((w=1;w<=6;w++)) do week=$(date --date "$w weeks ago" +"%G-%V") beg=$(date --date "monday $w weeks ago" +"%F") end=$(date --date "sunday $w weeks ago" +"%F") echo "$week beg=$beg end=$end" $(( ($(date --date $end +"%s") - $(date --date $beg +"%s")) / 86400 ) + 1) "days" done 2014-02 beg=2014-01-06 end=2014-01-12 7 days 2014-01 beg=2013-12-30 end=2014-01-05 7 days 2013-52 beg=2013-12-23 end=2013-12-29 7 days 2013-51 beg=2013-12-16 end=2013-12-22 7 days 2013-50 beg=2013-12-09 end=2013-12-15 7 days 2013-49 beg=2013-12-02 end=2013-12-08 7 days 

выглядит хорошо, но когда я делаю то же самое сегодня (вторник), я получаю следующее:

 2014-02 beg=2014-01-13 end=2014-01-12 0 days 2014-01 beg=2014-01-06 end=2014-01-05 0 days 2013-52 beg=2013-12-30 end=2013-12-29 0 days 2013-51 beg=2013-12-23 end=2013-12-22 0 days 2013-50 beg=2013-12-16 end=2013-12-15 0 days 2013-49 beg=2013-12-09 end=2013-12-08 0 days 

который выглядит не очень хорошо.

Итак, как назначить date чтобы получить границы недели в прошлом?

  • Проблема 2038 года
  • дата не принимает свой собственный результат
  • Отобразить все даты на номерах недель в UNIX
  • В bash, как вызвать переменную и обернуть кавычки вокруг ее значения как часть команды, не заставляя имя переменной стать строковым литералом?
  • Как представить формат даты в '2015120' в оболочке Linux?
  • Как печатать даты между двумя разными датами
  • Создать номер строки / «индекс» в пределах диапазона от начального значения даты
  • Как установить дату в формате Epoch
  • 2 Solutions collect form web for “Укажите согласованные границы недели, используя дату”

    Проблема в том, что в зависимости от текущего дня «воскресенье x недель назад» может быть до «понедельник x недель назад»:

    • Если сегодня понедельник, то «воскресенье x недель назад» = «понедельник x недель назад» + 6
    • Если сегодня не понедельник, то «воскресенье x недель назад» = «понедельник x недель назад» – 1

    Вместо того, чтобы принимать «воскресенье x недель назад» и «понедельник x недель назад», будет легче взять «воскресенье x недель назад» и «воскресенье x недель назад – 6 дней».

    С некоторыми другими исправлениями и упрощениями ошибок, вот ваш обновленный скрипт:

     #!/bin/bash for ((w=1;w<=6;w++)); do end=$(date --date "sun $w weeks ago" +%F) beg=$(date --date "sun $w weeks ago - 6 days" +%F) week=$(date --date "$beg" +%G-%V) echo "$week beg=$beg end=$end" $((($(date --date $end +%s) - $(date --date $beg +%s)) / 86400 + 1 )) "days" done 

    Заметьте, что я тоже изменил настройку week , чтобы основываться на beg .

    Однако вам все равно нужно помнить, какое воскресенье вы хотите выбрать в воскресенье: сегодня или за неделю до этого? Этот сценарий выберет воскресенье за ​​неделю до этого, а не сегодня. Если это не то, что вы хотите, то вы можете пересмотреть расчеты, основанные на понедельнике вместо воскресенья: возьмите «понедельник x недель назад» и «понедельник x недель назад + 6 дней»:

     for ((w=1;w<=6;w++)); do beg=$(date --date "mon $w weeks ago" +%F) end=$(date --date "mon $w weeks ago + 6 days" +%F) week=$(date --date "$w weeks ago" +%G-%V) echo "$week beg=$beg end=$end" $((($(date --date $end +%s) - $(date --date $beg +%s)) / 86400 + 1 )) "days" done 

    Вы можете использовать date +%u для поиска понедельника и воскресенья относительно заданной даты.

    Предполагая, что «0 недель назад» на этой неделе.

     for ((w=1;w<=6;w++)); do when=$(date --date "$w weeks ago") beg_offset=$(( $(date --date "$when" +%u) - 1)) beg=$(date --date "$when - $beg_offset days" +"%F") end_offset=$((6 - beg_offset)) end=$(date --date "$when + $end_offset days" +"%F") week=$(date --date "$when" +"%G-%V") days=$(( ( $(date --date "$end" +"%s") - $(date --date "$beg" +"%s") ) / 86400 + 1)) echo "$week beg=$beg end=$end $days days" done 
    Linux и Unix - лучшая ОС в мире.