Dans de nombreux métiers le travail se fait sur un rythme hebdomadaire et l’on parle beaucoup de numéro de semaine.
crédit image : www.electro-gn.com
En bons développeurs que nous sommes, nous offrons à nos utilisateurs une interface leur permettant de manipuler les données par numéro de semaine. On aurait tendance à peu réfléchir et à utiliser indifféremment la fonction php date(« W ») ou la fonction mySQL week( datetime ). Notez au passage qu’il s’agit d’un W majuscule et il ne faut pas confondre avec le w minuscule qui désigne l’indice du jour de la semaine.
Malheureusement tout n’est pas aussi simple et tout le monde ne compte pas les semaines de la même manière. Cela commence par le premier jour de la semaine, en France on commence les semaines le Lundi, dans les pays anglo-saxon c’est plutôt le dimanche. Vous pourriez ainsi vous demander longtemps pourquoi votre client vous parle du dimanche de la semaine 47 alors que d’après vous (et d’après votre fonction php) il s’agit de la semaine 46. Certaines entreprises françaises utilisent tout de même le dimanche comme 1er jour de la semaine, sisi, je vous jure !
Pour ne vraiment pas nous faciliter la vie, la 1er semaine de l’année n’est pas systématiquement celle du 1er janvier. Pour certains cette semaine sera la semaine 0 de l’année, pour d’autres la semaine 1 ; mais il est aussi possible de considérer cette semaine comme la dernière de l’année précédente.
Généralement s’est à ce moment que l’on se pose la question : « Comment sont normalement numérotées les semaines ? »
Il existe une norme ISO-8601 qui définit la première semaine de l’année comme celle contenant le 1er jeudi. Ainsi, si votre 1er janvier est un vendredi, il s’agira de la fin de la dernière semaine de l’année passée. Cette semaine sera par exemple la semaine 52 de l’année 2012. Démonstration : si vous faîtes date(« W », mktime(0, 0, 0, 1, 1, 2012)) vous obtenez bien 52. Dans cette même norme les semaines débutent par contre le Lundi.
En sql, par défaut la fonction week() renvoi un numéro de semaine compris entre 0 et 53. 0 si il s’agit d’une semaine de l’année précédente.
On pourrait penser que week(’2012-01-01′) renvoi 0 donc. Et bien non, car par défaut mySQL considère que les semaines commencent le dimanche ! Ce qui est le cas du 1er janvier 2012.
Le 1er janvier 2013 étant un mardi, il est issu de la semaine terminant 2012 et donc mySQL renvoi 0.
Ce avec quoi notre fonction php n’est pas d’accord, date(‘W’, mktime(0, 0, 0, 1, 1, 2013)) renvoi « 01″ car il est calé sur la norme ISO-8601.
Depuis mySQL 4.0 il est possible de définir quel comportement doit avoir la fonction week en passant un deuxième paramètre. voir la documentation.
Ici, nous pourrons utiliser la valeur « 3″ comme deuxième paramètre qui correspond à la définition de la norme ISO-8601.
C’est donc bien 1 que renverra week(’2013-01-01′, 3)
Bien, et comment faire en php pour les clients souhaitant tout de même commencer un dimanche tout en conservant la règle du jeudi (au moins 3 jours dans la semaine) ?
Pas de miracle : il faut calculer le jour courant et, s’il s’agit d’un dimanche, ajouter 1 à la semaine en prenant soin de vérifier l’intervalle 1-52.
Dernier point intéressant. Si vous souhaitez afficher le numéro de semaine et l’année, vous auriez tendance à utiliser date(‘W-Y’), ce qui, pour le 1er janvier 2012 affichera 52-2012.
D’un point de vue de php, Y est l’année de la date, or on aimerait afficher l’année de la semaine concernée, dans notre cas 2011.
Et bien sachez que l’option « o » fait exactement cela. date(‘W-o’, mktime(0, 0, 0, 1, 1, 2012)) renvoit 52-2011 ce qui signifie « La semaine 52 de l’année 2011″.