Como usar o comando date para descobrir qual será a data "segunda-feira semana 40"?


11

Como posso usar o comando date para converter algo como "segunda-feira semana 40" em uma data ISO?

Estou brincando com algo assim:

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

E a data que estou procurando seria 03/10/2011.

Mas meu problema é que essa sequência de datas não é válida, portanto, preciso de outra abordagem para resolver esse problema.

/Obrigado


O link a seguir é sobre o que determina em qual dia do ano uma semana numerada começa. Numeração da semana (Wikipedia) . Explica efetivamente o motivo pelo qual o 1º de janeiro deste ano está na semana 52 da ISO. A %Vsequência de formato usada por 'usuário desconhecido' informa o número da semana ISO.
precisa saber é o seguinte

Respostas:


4

Muito feio e provavelmente funciona apenas com o 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'

Testado apenas para o seu exemplo de 3 de outubro, pode falhar em alguns outros casos.


Atualização : se você não tiver um código de idioma, precisará especificar a saída a partir da data interna para começar a trabalhar. (E% F é apenas AAAA-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"

1
Você perdeu a formatação da saída a partir da data interna para que a externa possa usá-la corretamente.
Johan

@ John, não tive problemas em usar o formato padrão. Talvez seja específico do local? Eu uso en_US. Bom ponto de qualquer maneira.
manatwork

Para a data em que uso o código de idioma sueco, existe a diferença.
11117 Johan

Obrigado pelo ajuste de localidade. Eu tenho um formato de data personalizado e tive o mesmo problema. Eu quase o resolvi, mas agora você o postou, vou usar o seu ajuste; é melhor.
precisa saber é o seguinte

Não havia nenhum requisito para que isso fosse uma linha única. Seria melhor dividir isso em várias linhas, usando variáveis ​​temporárias com nomes descritivos para deixar claro como funciona. Ele também pressupõe que 1º de janeiro seja no mesmo número da semana a cada ano, o que não é o caso já observado por @ Peter.O.
Adam Spiers

5

Uma abordagem alternativa:

date --date "+$((40-$(date +%V)))weeks last monday"  +"%F"
  • 40 é a semana que você procura
  • data +% V retorna a semana atual (35)
  • 40-35 = 5, que é o número de semanas a adicionar
  • a partir daí, procure a última segunda-feira

boa e funciona com a minha configuração de data personalizada.
precisa saber é o seguinte

Esta é uma ideia inteligente, mas não funciona. Por exemplo, se hoje é segunda-feira na semana 41 (ou seja, date +%Vretorna 41), o --datevalor do parâmetro será +-1weeks last monday, que é na verdade quinze dias atrás, não sete dias atrás.
Adam Spiers

Não tenho certeza se entendi sua crítica. É 2013 este ano, então o exemplo da pergunta não se encaixa. Qual deve ser a data absoluta da pergunta e, em vez disso, qual é a minha abordagem (talvez: por que)?
usuário desconhecido

@ AdamSpiers: Meu calendário é exibido como segunda-feira, semana 40, 30 de setembro, que é o que meu algo produz (hoje).
usuário desconhecido

@userunknown Isso porque você está testando seu código hoje, que é uma terça-feira, que vem depois de segunda-feira. Se você tivesse testado seu código ontem, ele teria quebrado. Para torná-lo mais óbvio, tente executar date -d 'last monday'. Voltará ontem. O que você acha que teria dito se você tivesse rodado ontem?
Adam Spires

1

OK, aqui está a minha tentativa. Ele rouba idéias das outras respostas e tenta tornar a lógica mais fácil de seguir. Isso é baseado no sistema ISO 8601, portanto, não será correto se você mora em países como EUA ou Canadá, mas deve ser facilmente ajustável para esses países.

# 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" )
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.