¿Cómo utilizar el comando de fecha para averiguar qué fecha será "lunes semana 40"?

11

¿Cómo puedo usar el comando de fecha para convertir algo como "lunes semana 40" en una fecha ISO?

Estoy jugando con algo como esto:

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

Y la fecha que estoy buscando sería 2011-10-03.

Pero mi problema es que esta cadena de fecha no es válida, por lo que necesito otro enfoque para resolver este problema.

/Gracias

Johan
fuente
El siguiente enlace trata sobre qué determina en qué día del año comienza una semana numerada . Numeración de semana (Wikipedia) . Explica efectivamente por qué el 1 de enero de este año está en la semana 52 de ISO. La %Vsecuencia de formato utilizada por 'usuario desconocido' informa el número de semana de ISO.
Peter.O

Respuestas:

4

Realmente feo y probablemente solo funciona 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'

Probado solo para su ejemplo del 3 de octubre, puede fallar en algunos otros casos.


Actualización : si tiene una configuración regional no inglesa, debe especificar el resultado de la fecha interna para poder trabajar. (Y% F solo es 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"
hombre trabajando
fuente
1
Se olvidó de formatear la salida desde la fecha interna para que la externa pueda usarla correctamente.
Johan
@Johan, no tuve ningún problema con el uso del formato predeterminado. Tal vez es local específico? Yo uso en_US. Buen punto de todos modos.
manatwork
Para la fecha utilizo la configuración regional sueca, así que existe la diferencia.
Johan
Gracias por el ajuste local. Tengo un formato de fecha personalizado y tuve el mismo problema. Casi lo había solucionado, pero ahora que lo ha publicado, usaré su ajuste; es mejor.
Peter.O
No había ningún requisito para que esto fuera de una sola línea. Sería mejor dividir esto en varias líneas, utilizando variables temporales con nombres descriptivos para dejar en claro cómo funciona. También supone que el 1 de enero está en el mismo número de semana cada año, que no es el caso como ya lo señaló @ Peter.O.
Adam Spires
5

Un enfoque alternativo:

date --date "+$((40-$(date +%V)))weeks last monday"  +"%F"
  • 40 es la semana que buscas
  • fecha +% V devuelve la semana actual (35)
  • 40-35 = 5, que es el número de semanas para agregar
  • a partir de ahí, busca el último lunes
usuario desconocido
fuente
bueno, y funciona con mi configuración de fecha personalizada.
Peter.O
Esta es una idea inteligente, pero no funciona. Por ejemplo, si hoy es lunes en la semana 41 (es decir, date +%Vretornos 41), entonces el --datevalor del parámetro será +-1weeks last monday, que en realidad es hace quince días, no hace 7 días.
Adam Spires
No estoy seguro si entiendo tu crítica. Es 2013 este año, por lo que el ejemplo de la pregunta no encaja. ¿Cuál debería ser la fecha absoluta para la pregunta y qué devuelve mi enfoque (tal vez: por qué)?
usuario desconocido
@AdamSpiers: Mi calendario se muestra como el lunes, semana 40, el 30 de septiembre, que es lo que produce mi algo (hoy).
Usuario desconocido
@userunknown Eso es porque estás probando tu código hoy, que es un martes, que viene después del lunes. Si hubiera probado su código ayer, se habría roto. Para hacerlo más obvio, intente correr date -d 'last monday'. Regresará ayer. ¿Qué crees que habría dicho si lo hubieras ejecutado ayer?
Adam Spires
1

OK, aquí está mi intento. Roba ideas de las otras respuestas e intenta hacer que la lógica sea más fácil de seguir. Esto se basa en el sistema ISO 8601, por lo que no será correcto si vives en países como EE. UU. O Canadá, pero debería ser fácilmente ajustable para esos 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" )
}
Adam Spires
fuente