Comment utiliser la commande date pour connaître la date de la «semaine du lundi 40»?

11

Comment puis-je utiliser la commande date pour convertir quelque chose comme "lundi semaine 40" en une date ISO?

Je joue avec quelque chose comme ça:

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

Et la date que je recherche serait le 2011-10-03.

Mais mon problème est que cette chaîne de date n'est pas valide, j'ai donc besoin d'une autre approche pour résoudre ce problème.

/Merci

Johan
la source
Le lien suivant indique ce qui détermine le jour de l'année commence une semaine numérotée . Numérotation des semaines (Wikipedia) .. Cela explique en effet pourquoi le 1er janvier de cette année est dans la semaine ISO 52. La %Vséquence de format utilisée par 'utilisateur inconnu' rapporte le numéro de semaine ISO.
Peter.O

Réponses:

4

Vraiment moche et ne fonctionne probablement qu'avec 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'

Testé uniquement pour votre exemple du 3 octobre, peut échouer pour certains autres cas.


Mise à jour : Si vous avez un environnement local non eng, vous devez spécifier la sortie de la date interne pour vous mettre au travail. (Et% F est simplement AAAA-MM-JJ).

date -d "$(date -d "$(date +'%Y-01-01') +40 weeks" +"%F") -$(date -d "$(date +'%Y-01-01') +40 weeks" +%w) days +1 day" +"%F"
homme au travail
la source
1
Vous avez manqué de formater la sortie à partir de la date intérieure afin que l'extérieur puisse l'utiliser correctement.
Johan
@Johan, je n'ai eu aucun problème avec l'utilisation du format par défaut. Peut-être que c'est spécifique aux paramètres régionaux? J'utilise en_US. Bon point quand même.
manatwork
Pour la date, j'utilise les paramètres régionaux suédois, donc il y a la différence.
Johan
Merci pour l'ajustement des paramètres régionaux. J'ai un format de date personnalisé et j'ai eu le même problème .. Je l'avais presque réglé, mais maintenant que vous l'avez posté, je vais utiliser votre réglage; c'est mieux.
Peter.O
Il n'y avait aucune exigence pour qu'il s'agisse d'un vol simple. Il serait préférable de diviser cela en plusieurs lignes, en utilisant des variables temporaires avec des noms descriptifs pour expliquer clairement comment cela fonctionne. Il suppose également que le 1er janvier est dans le même numéro de semaine chaque année, ce qui n'est pas le cas comme l'a déjà noté @ Peter.O.
Adam Spires
5

Une approche alternative:

date --date "+$((40-$(date +%V)))weeks last monday"  +"%F"
  • 40 est la semaine que vous recherchez
  • date +% V renvoie la semaine en cours (35)
  • 40-35 = 5, qui est le nombre de semaines à ajouter
  • à partir de là, cherchez le dernier lundi
Utilisateur inconnu
la source
bon, et cela fonctionne avec mon réglage de date personnalisé.
Peter.O
C'est une idée intelligente, mais cela ne fonctionne pas. Par exemple, si aujourd'hui est lundi de la semaine 41 (c'est-à-dire date +%Vretourne 41), alors la --datevaleur du paramètre sera +-1weeks last monday, qui est en fait il y a une quinzaine, pas 7 jours.
Adam Spires
Je ne sais pas si je comprends votre critique. C'est 2013 cette année, donc l'exemple de la question ne correspond pas. Quelle devrait être la date absolue de la question et que renvoie mon approche à la place (peut-être: pourquoi)?
utilisateur inconnu
@AdamSpiers: Mon calendrier s'affiche comme lundi, semaine 40, 30 septembre, ce que mon algo rapporte (aujourd'hui).
utilisateur inconnu
@userunknown C'est parce que vous testez votre code aujourd'hui, qui est un mardi, qui vient après lundi. Si vous aviez testé votre code hier, il se serait cassé. Pour le rendre plus évident, essayez de courir date -d 'last monday'. Il reviendra hier. Que pensez-vous qu'il aurait dit si vous l'aviez exécuté hier?
Adam Spires
1

OK, voici ma tentative. Il dérobe les idées des autres réponses et tente de rendre la logique plus facile à suivre. Ceci est basé sur le système ISO 8601, il ne sera donc pas correct si vous vivez dans des pays tels que les États-Unis ou le Canada, mais devrait être facilement réglable pour ces pays.

# 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
la source