Jak użyć polecenia date, aby dowiedzieć się, jaka będzie data „poniedziałkowy tydzień 40”?

11

Jak mogę użyć polecenia date, aby przekonwertować coś w stylu „poniedziałkowy tydzień 40” na datę ISO?

Gram z czymś takim:

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

A data, której szukam, to 2011-10-03.

Ale moim problemem jest to, że ten ciąg daty jest nieprawidłowy, dlatego potrzebuję innego podejścia, aby rozwiązać ten problem.

/Dzięki

Johan
źródło
Poniższy link dotyczy tego, co określa, w który dzień roku rozpoczyna się numerowany tydzień . Numeracja tygodni (Wikipedia) . To skutecznie wyjaśnia, dlaczego 1 stycznia tego roku przypada na tydzień ISO 52. %VSekwencja formatów używana przez „nieznanego użytkownika” podaje numer tygodnia ISO.
Peter.O

Odpowiedzi:

4

Naprawdę brzydka i prawdopodobnie działa tylko z 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'

Testowany tylko na przykład z 3 października może się nie powieść w niektórych innych przypadkach.


Aktualizacja : jeśli masz lokalizację inną niż eng, musisz określić dane wyjściowe z wewnętrznej daty, aby zabrać się do pracy. (A% F to po prostu RRRR-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"
człowiek w pracy
źródło
1
Brakowało sformatowania wyniku od wewnętrznej daty, aby zewnętrzny mógł go poprawnie użyć.
Johan
@Johan, nie miałem problemu z użyciem domyślnego formatu. Może to zależy od regionu? Używam en_US. W każdym razie dobry punkt.
manatwork
W przypadku daty używam szwedzkich ustawień regionalnych, więc jest różnica.
Johan
Dziękujemy za dostosowanie ustawień regionalnych. Mam niestandardowy format daty i miałem ten sam problem. Prawie go uporządkowałem, ale teraz go opublikowałeś. Wykorzystam twoje poprawki; to jest lepsze.
Peter.O
Nie było wymogu, aby było to jedno-liniowe. Lepiej byłoby podzielić to na wiele wierszy, używając zmiennych tymczasowych z opisowymi nazwami, aby wyjaśnić, jak to działa. Zakłada również, że 1 stycznia każdego roku ma ten sam numer tygodnia, co nie jest tak, jak to już zauważył @ Peter.O.
Adam Spiers,
5

Alternatywne podejście:

date --date "+$((40-$(date +%V)))weeks last monday"  +"%F"
  • 40 to tydzień, którego szukasz
  • data +% V zwraca bieżący tydzień (35)
  • 40–35 = 5, czyli liczba tygodni do dodania
  • stamtąd szukaj ostatniego poniedziałku
nieznany użytkownik
źródło
dobry i działa z moim niestandardowym ustawieniem daty.
Peter.O
To sprytny pomysł, ale nie działa. Na przykład, jeśli dzisiaj jest poniedziałek w 41 tygodniu (tj. date +%VPowrót 41), wówczas --datewartość parametru będzie wynosić +-1weeks last monday, co w rzeczywistości dwa tygodnie temu, a nie 7 dni temu.
Adam Spiers,
Nie jestem pewien, czy rozumiem twoją krytykę. W tym roku jest rok 2013, więc przykład z pytania nie pasuje. Jaka powinna być bezwzględna data pytania i jakie zamiast tego powraca moje podejście (może: dlaczego)?
użytkownik nieznany
@AdamSpiers: Mój kalendarz wyświetla się jako poniedziałek, 40. tydzień 30 września. To właśnie daje mój algo (dziś).
użytkownik nieznany
@userunknown To dlatego, że testujesz swój kod dzisiaj, czyli we wtorek, który nastąpi po poniedziałku. Jeśli przetestowałeś swój kod wczoraj, złamałby się. Aby było to bardziej oczywiste, spróbuj uruchomić date -d 'last monday'. Wróci wczoraj. Jak myślisz, co by powiedział, gdybyś uruchomił go wczoraj?
Adam Spires,
1

OK, oto moja próba. Kradnie pomysły z innych odpowiedzi i stara się ułatwić logikę. Jest to oparte na systemie ISO 8601, więc nie będzie poprawne, jeśli mieszkasz w krajach takich jak USA lub Kanada, ale powinno być łatwo regulowane dla tych krajów.

# 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" )
}
Adam Spiers
źródło