Как использовать команду даты для обнаружения, какова дата “неделя в понедельник 40” будет?

Я полагаю, что только обозначает буквами, числа, и подчеркивание позволяется для переменных удара. Дело обстоит так на многих языках программирования (JavaScript, являющийся исключением).

Я рекомендую не иметь Вашего сценария, зависят от тех типов имен переменной.

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

11
01.09.2011, 16:51
3 ответа

Действительно ужасный и вероятно работает только с GNU date:

date -d "$( date -d "$( date +'%Y-01-01' ) +40 weeks") -$( date -d "$( date +'%Y-01-01' ) +40 weeks" +'%w' ) days+1 day" +'%Y-%m-%d'

Протестированный только на Ваш 3 октября пример, может перестать работать для некоторых других случаев.


Обновление: Если у Вас есть не локаль инженера, необходимо указать вывод с внутренней даты для получения до работать. (И %F просто является YYYY-MM-DD).

date -d "$(date -d "$(date +'%Y-01-01') +40 weeks" +"%F") -$(date -d "$(date +'%Y-01-01') +40 weeks" +%w) days +1 day" +"%F"
4
27.01.2020, 19:59
  • 1
    Вы отсутствовали для форматирования вывода с внутренней даты, таким образом, внешнее могло использовать его правильно. –  Johan 01.09.2011, 14:19
  • 2
    @Johan, у меня не было проблемы с использованием формата по умолчанию. Возможно, это - конкретная локаль? Я использую en_US. Положительная сторона так или иначе. –  manatwork 01.09.2011, 14:34
  • 3
    Для даты я использую шведскую локаль, таким образом, существует различие. –  Johan 01.09.2011, 16:09
  • 4
    Спасибо за корректировку локали. Я имею пользовательский формат даты и имел ту же проблему.. Я почти уладил его, но теперь Вы отправили его, я буду использовать Вашу тонкую настройку; это лучше. –  Peter.O 01.09.2011, 17:32
  • 5
    Не было никакого требования для этого, чтобы быть остротой. Было бы лучше разделить это на несколько строк, с помощью временных переменных с описательными именами, чтобы прояснить, как это работает. Это также предполагает, что 1-й Jan находится в том же недельном числе каждый год, которое не имеет место, как уже отмечено @Peter. O. –  Adam Spiers 02.09.2013, 14:16

Альтернативный подход:

date --date "+$((40-$(date +%V)))weeks last monday"  +"%F"
  • 40 неделя, которую Вы ищете
  • дата + %V возвращает текущую неделю (35)
  • 40-35 = 5, который является числом недель для добавления
  • оттуда, ищите в прошлый понедельник
5
27.01.2020, 19:59
  • 1
    хороший, и это работает с моей пользовательской установкой даты. –  Peter.O 01.09.2011, 17:31
  • 2
    Это - умная мысль, но она не работает. Например, если сегодня понедельник на неделе 41 (т.е. date +%V возвраты 41), затем --date значение параметра будет +-1weeks last monday, который является на самом деле две недели назад, не 7 дней назад. –  Adam Spiers 02.09.2013, 14:09
  • 3
    я не уверен, понимаю ли я Ваш критический анализ. Это - 2013 в этом году, таким образом, пример от вопроса не соответствует. Что должно быть абсолютной датой вопроса, и что делает мой возврат подхода вместо этого (возможно: почему)? –  user unknown 03.09.2013, 01:32
  • 4
    @AdamSpiers: Мой календарь отображается как в понедельник, неделя 40 30-го сентября, который является тем, к чему мой алгоритм приводит (сегодня). –  user unknown 03.09.2013, 01:38
  • 5
    @userunknown Поэтому, Вы тестируете свой код сегодня, который является вторником, который наступает после понедельника. При тестировании кода вчера он имел бы, повредился. Для создания этого более очевидным попытайтесь работать date -d 'last monday'. Вчера это возвратится. Что Вы думаете, что это сказало бы, выполнили ли Вы вчера его? –  Adam Spiers 03.09.2013, 16:38

Хорошо, вот моя попытка. Это крадет идеи из других ответов и пытается сделать логику легче следовать. Это основано на системе ISO 8601, таким образом, это не будет корректно, если Вы будете жить в странах, таких как США или Канада, но должны будете быть легко корректируемыми для тех стран.

# sets $week_start to a representation of Monday of the given week
# number formatted via the given format, and similarly sets
# $week_end to Friday of the same week.
get_week_range () {
    week_num="$1" date_format="$2"

    # Most of the world adhere to ISO 8601 which states that weeks begin on Monday
    # and Jan 4th is always in week #1:
    #
    #   http://en.wikipedia.org/wiki/ISO_week_date
    #
    # For other week numbering systems (e.g. USA, Canada), see:
    #
    #   http://en.wikipedia.org/wiki/Seven-day_week#Week_numbering
    day_in_week_1=$( date +'%Y-01-04' )
    day_num_in_week_1=$( date -d $day_in_week_1 +%u ) # 1 is Monday
    days_from_week_1_start=$(( $day_num_in_week_1 - 1 ))
    # This is a Monday:
    start_of_week_1=$( date -d "$day_in_week_1 - $days_from_week_1_start days" +%F )

    week_delta="$(( $week_num - 1 ))"
    # Monday:
    week_start=$( date -d "$start_of_week_1 + $week_delta weeks"          +"$date_format" )
    # Friday:
    week_end=$(   date -d "$start_of_week_1 + $week_delta weeks + 4 days" +"$date_format" )
}
1
27.01.2020, 19:59

Теги

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