Як скористатися командою дати, щоб дізнатися, якою буде дата «понеділок 40»?


11

Як я можу використовувати команду date для перетворення чогось типу "понеділок 40" у дату ISO?

Я граю з чимось подібним:

date --date='monday week 40' +'%Y-%m-%d'

А дата, яку я шукаю, буде 2011-10-03.

Але моя проблема полягає в тому, що цей рядок дати недійсний, тому мені потрібен інший підхід для вирішення цієї проблеми.

/Спасибі


Наступне посилання стосується того, що визначає, в який день року починається нумерований тиждень . Нумерація тижнів (Вікіпедія) . Це ефективно пояснює, чому 1 січня цього року проходить 52 тиждень ISO. Формальна %Vпослідовність, що використовується "невідомим користувачем", повідомляє номер тижня ISO.
Пітер.O

Відповіді:


4

Дійсно некрасиво і, ймовірно, працює лише з 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 просто - РРРР-ММ-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"

1
Ви пропустили форматувати висновок із внутрішньої дати, щоб зовнішня могла правильно його використовувати.
Йоган

@Johan, у мене не було проблем із використанням формату за замовчуванням. Можливо, це локально? Я використовую en_US. Гарний момент все одно.
манатура

Для дати я використовую шведський локал, тому є різниця.
Йоган

Дякуємо за налаштування місцевості. У мене є власний формат дати та була така ж проблема .. Я майже його розібрав, але тепер ви опублікували його, я використаю ваш твіт. краще.
Пітер.O

Для цього не було вимоги бути однолінійним. Було б краще розділити це на кілька рядків, використовуючи тимчасові змінні з описовими іменами, щоб зрозуміти, як це працює. Він також передбачає, що 1 січня щороку знаходиться в одній і тій же кількості тижня, що не так, як уже зазначав @ Peter.O.
Адам Шпієр

5

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

date --date "+$((40-$(date +%V)))weeks last monday"  +"%F"
  • 40 - тиждень, який ви шукаєте
  • дата +% V повертає поточний тиждень (35)
  • 40-35 = 5, що додати кількість тижнів
  • звідти шукайте останній понеділок

хороший, і він працює з моїм спеціальним налаштуванням дати.
Пітер.O

Це розумна ідея, але вона не працює. Наприклад, якщо сьогодні понеділок на тижні 41 (тобто date +%Vповертається 41), то --dateзначення параметра буде таким +-1weeks last monday, яке насправді за тиждень тому, а не 7 днів тому.
Адам Шпієр

Я не впевнений, чи розумію я вашу критику. Це 2013 рік, тому приклад із запитання не підходить. Якою має бути абсолютна дата для запитання, і що замість цього повертається мій підхід (можливо: чому)?
користувач невідомий

@AdamSpiers: Мій календар відображається як понеділок, 40 тиждень, 30 вересня, що дає моє альго (сьогодні).
користувач невідомий

@userunknown Це тому, що ви протестуєте свій код сьогодні, це вівторок, який настає після понеділка. Якби ви протестували свій код вчора, він би зламався. Щоб зробити це більш очевидним, спробуйте запустити date -d 'last monday'. Він повернеться вчора. Як ви думаєте, що це могло б сказати, якби ви його вчора запустили?
Adam Spiers

1

Гаразд, ось моя спроба. Він краде ідеї з інших відповідей і намагається полегшити логіку. Це засновано на системі 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" )
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.