%

Hugo : Obtenir le numéro de semaine dans l'année (astuce)

Obtenir le numéro d'une semaine donnée dans l'année !

Détails relatifs à l'article

Article publié, le
et modifié le
4 minutes de lecture

Cet article contient 764 mots.

Identifiant de l'article : tag:doc.huc.fr.eu.org,2026-05-04:/fr/web/hugo/numero-semaine/#ba4e036770af61d17af4a01853f81171f420b17982ef710ff05cf282525ab174


Source brute de l'article :
Commit version : 9bf3d7b


Cet article est aussi disponible sur le protocole Gemini :
gemini://doc.huc.fr.eu.org/fr/web/hugo/numero-semaine.gmi


Description

S’il est une chose que, pour l’instant et nativement, le SSG Hugo n’est pas capable de fournir, c’est bien le numéro d’une semaine d’année.

Pourtant le langage Go fournit la méthode IsoWeek(). Mais ce n’est pas implémentée dans Hugo, c’est “en cours de réflexion” !

Trouver le numéro de semaine répond à un besoin, certes peu courant, mais utile. Admettons que vous créez une newsletter hebdomadaire ;)

Je vais vous présenter deux méthodes différentes :

getisoweek

Dans un premier temps, création d’un modèle partial : /func/getIsoWeek

Voici le code :

{{- $date := time . -}}
{{- $weekday := $date.Weekday }}
{{/* 1. Normalize Weekday (Mon=1 ... Sun=7) */}}
{{- $isoDay := cond (eq $weekday 0) 7 (int $weekday) -}}
{{/* 2. Find Thursday (ISO Week belongs to the year of its Thursday) */}}
{{- $offset := sub 4 $isoDay -}}
{{- $thursday := $date.AddDate 0 0 $offset -}}
{{/* 3. Calculate Week Number */}}
{{- $isoYear := $thursday.Year -}}
{{- $isoWeek := add (div (sub $thursday.YearDay 1) 7) 1 -}}
{{/* 4. Return the data */}}
{{- $str := dict "week" (printf "%02d" $isoWeek) "year" (printf "%04d" $isoYear) -}}
{{- $data := dict "week" $isoWeek "year" $isoYear "str" $str -}}
{{- return $data -}}

L’appel se faisant :

{{- partial "func/getisoweek" .Date -}}

Ou toute autre variable faisant appel à Time, tel que now.

⇒ Remarquez l’appel à la “fonction” getIsoWeek :

  • si je veux les valeurs en entier de la semaine et l’année, j’appele $data.week et $data.year
  • si je veux les valeurs en chaîne de caractères, j’appele $data.str.week et $data.str.year

Personnellement, j’ai en plus crée un modèle partial nommé utils/formatIsoDate dont le code est le suivant :

{{- $data := partial "func/getIsoWeek" . -}}
{{- return (printf "w%02d-y%04d" $data.week $data.year) -}}

Et que je peux ainsi appeler soit depuis le fichier default.md dans l’archetypes, soit ailleurs dans les modèles ou les shortcodes, selon l’envie, tels :

{{ partial "utils/formatIsoDate" .Date }} ou {{ partial "utils/formatIsoDate" now }}.

getweeknumber

Cette deuxième manière d’obtenir le numéro de semaine est un peu plus ardu !

Cette fois-ci, j’ai deux fichiers principaux.

⇒ le premier nommé func/splitNameYMO a pour fonction “d’éclater” une date normée (AAAA-MM-DD) en jour, mois, année correspondants et de retourner un dictionnaire.

{{- $str := split . "-" -}}
{{- $d = (int (index $str 2)) -}}
{{- $m = (int (index $str 1)) -}}
{{- $y = (int (index $str 0)) -}}
{{- return (dict "day" $d "month" $m "year" $y) -}}

Si j’ai créé ce fichier, c’est parce qu’au-travers de mon code, je le réutilise souvent…

⇒ le deuxième fichier est la fonction primordiale, nommé func/getWeekNumber

{{- $date := "" -}}
{{- $tz := site.Params.timeZone -}}
{{- $week := 0 -}}

{{ $type := printf "%T" . }}

{{ if eq $type "string" }}

    {{- $data := partial "func/splitNameYMO" . }}
    {{- $date = time (printf "%04d-%02d-%02d" $data.year $data.month $data.day) $tz -}}

{{ else }}

    {{- $date = time . $tz -}}

{{- end -}}

{{/* Calcul 'doy: day of the year', 'dow: day of the week' */}}
{{- $doy := $date.YearDay -}}
{{- $dow := int $date.Weekday -}}
{{- $year := $date.Year -}}

{{/* calcul week number */}}
{{- $week = div (add (sub $doy $dow) 10) 7 -}}
{{- if eq $dow 0 -}}
    {{- $week = sub $week 1 -}}
{{- end -}}

{{- $str := dict "week" (printf "%02d" $week) "year" (printf "%04d" $year) -}}
{{- $data := dict "week" $week "year" $year "str" $str -}}
{{- return $data -}}

Explications :

  • En premier lieu, je cherche à savoir de quel type est la valeur que j’injecte dans l’appel du fichier, si c’est une string ou autre chose, en l’occurence une valeur de temps — gardez à l’esprit que Hugo ne sait pas annoncer un type de valeur pour une valeur de temps, néanmoins dans le référentiel, elle est définie à Time.time.

  • Ensuite, je cherche à quel jour de l’année correspond la date ($doy), quelle est correspondance du jour dans la semaine ($dow) et pour finir l’année, bien-sûr.

  • Le calcul du numéro de semaine est connu :

    • il faut soustraire le jour de la semaine au jour de l’année
    • ajouter l’entier 10
    • et diviser le tout par 7.
    • et pour finir si le jour de la semaine est un dimanche, je soustrais 1 au numéro de semaine trouvé — c’est relatif à Hugo, dont les semaines commencent le dimanche.

Voilà deux manières différentes de faire la même chose : une recherche de numéro de semaine !

Documentation

Remerciement


Enjoy-ID!
Enjoy-IT!