Come utilizzare il comando date per scoprire quale data sarà “lunedì 40 settimana”?


11

Come posso usare il comando date per convertire qualcosa come "lunedì 40 settimana" in una data ISO?

Sto giocando con qualcosa del genere:

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

E la data che sto cercando sarebbe il 2011-10-03.

Ma il mio problema è che questa stringa di date non è valida, quindi ho bisogno di un altro approccio per risolvere questo problema.

/Grazie


Il seguente link riguarda ciò che determina in quale giorno dell'anno inizia una settimana numerata . Numerazione delle settimane (Wikipedia) . Spiega in modo efficace perché il 1 ° gennaio di quest'anno è nella settimana ISO 52. La %Vsequenza di formati utilizzata da "utente sconosciuto" riporta il numero della settimana ISO.
Peter

Risposte:


4

Davvero brutto e probabilmente funziona solo con 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'

Testato solo per il tuo esempio del 3 ottobre, potrebbe non riuscire in alcuni altri casi.


Aggiornamento : se si dispone di una locale non inglese, è necessario specificare l'output dalla data interna per poter funzionare. (E% F è solo AAAA-MM-GG).

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
Hai perso di formattare l'output dalla data interna in modo che l'esterno potesse usarlo correttamente.
Johan,

@Johan, non ho avuto problemi con l'utilizzo del formato predefinito. Forse è locale specifico? Uso en_US. Buon punto comunque.
Manatwork

Per la data in cui uso la locale svedese, quindi c'è la differenza.
Johan,

Grazie per l'adeguamento delle impostazioni locali. Ho un formato data personalizzato e ho avuto lo stesso problema .. L'ho quasi risolto, ma ora l'hai pubblicato userò il tuo tweak; è meglio.
Peter.O

Non era necessario che questo fosse un liner. Sarebbe meglio dividerlo in più righe, usando variabili temporanee con nomi descrittivi per chiarire come funziona. Presuppone inoltre che il 1 ° gennaio si trovi nello stesso numero settimanale ogni anno, il che non è il caso come già notato da @ Peter.O.
Adam Spires,

5

Un approccio alternativo:

date --date "+$((40-$(date +%V)))weeks last monday"  +"%F"
  • 40 è la settimana che cerchi
  • data +% V restituisce la settimana corrente (35)
  • 40-35 = 5, che è il numero di settimane da aggiungere
  • da lì, cerca l'ultimo lunedì

buono, e funziona con la mia impostazione personalizzata della data.
Peter.O

Questa è un'idea intelligente, ma non funziona. Ad esempio, se oggi è lunedì nella settimana 41 (ovvero date +%Vrestituisce 41), allora il --datevalore del parametro sarà +-1weeks last monday, che in realtà è due settimane fa, non 7 giorni fa.
Adam Spires,

Non sono sicuro di aver compreso la tua critica. È il 2013 quest'anno, quindi l'esempio della domanda non si adatta. Quale dovrebbe essere la data assoluta per la domanda e cosa restituisce invece il mio approccio (forse: perché)?
utente sconosciuto

@AdamSpiers: il mio calendario viene visualizzato come lunedì, settimana 40 il 30 settembre, che è ciò che il mio algo produce (oggi).
utente sconosciuto

@userunknown Questo perché stai testando il tuo codice oggi, che è un martedì, che arriva dopo lunedì. Se ieri avessi testato il tuo codice, si sarebbe rotto. Per renderlo più ovvio, prova a correre date -d 'last monday'. Tornerà ieri. Cosa pensi che avrebbe detto se l'avessi eseguito ieri?
Adam Spires,

1

OK, ecco il mio tentativo. Ruba idee dalle altre risposte e cerca di rendere più facile seguire la logica. Questo si basa sul sistema ISO 8601, quindi non sarà corretto se vivi in ​​paesi come Stati Uniti o Canada, ma dovrebbe essere facilmente regolabile per quei paesi.

# 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" )
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.