Ne Pas Déranger : Apple confond yyyy et YYYY ? (MAJ)

Ce début d’année a (encore) été marqué par un bug dans la gestion des dates sur iOS. Et certains essayent d’expliquer ce bug, qui serait issu d’une simple confusion entre yyyy et YYYY.

Comme le précise Laurent, les calculs sont faux, même si le résultat semble cohérent.


Je vais essayer de faire simple.

Pour calculer les dates, il existe plusieurs méthodes, et une utilise YYYY comme convention pour l’année, l’autre utilise yyyy. Dans le premier cas, on est dans ce qu’on appelle la « Numérotation ISO des semaines ». Ce système de comptage est parfois utilisé pour une raison : il définit des semaines qui font toutes 7 jours, ce qui permet de simplifier certains calculs mais induit des décalages dans certains cas. Dans ce mode, il faut que le lundi de la première semaine soit dans la même année que le jeudi de la première semaine. En 2013, le 1er janvier est tombé un mardi et la semaine « ISO » commence donc le 7 janvier 2013. Le lundi précédent n’est pas valable : il s’agit du 31 décembre 2012. Quand on est dans ce mode de calcul, tous les jours qui précèdent la première semaine ne font donc pas partie de 2013 mais bien de 2012. Dans ce calendrier précis, l’année 2012 se termine donc le 6 janvier 2013.

L’année ISO définit comme semaine 1 la semaine du premier jeudi de janvier. Cette année, l’année ISO commence donc le 31 janvier, qui fait donc stricto sensu partie de 2013 pour ce calendrier.

Point intéressant, le bug va se corriger — comme l’indique Apple — le 7 janvier.

Dans l’autre convention, plus classique, l’année commence le 1er janvier et le comptage des semaines est donc faussé : la première semaine ne fait pas nécessairement 7 jours.

Maintenant, regardons comment le bug va apparaître : iOS va activer la fonction Ne Pas Déranger à un moment précis, une date en 2012 ou en 2013. Il va ensuite paramétrer une date d’arrêt, la même date avec x heures de plus. Un démon va ensuite être lancé pour vérifier si la fonction doit être désactivée et c’est là que ça va coincer : un développeur a a priori utilisé YYYY au lieu de yyyy et donc le démon pense qu’il est encore en 2012 alors que la date renvoyée par le système est bien 2013. Et comme la date d’arrêt se trouve donc avant la date réelle pour le programme, la fonction ne se coupe tout simplement pas.

Un exemple : la fonction est activée par la date système le 2 janvier 2013 à 23 heures. La date d’arrêt est programmée pour le 3 janvier 2013 à 7 heures. Tout se passe bien : les dates sont bonnes. Quand le démon va calculer la date, par contre, ça va coincer : en ISO, le 3 janvier est en 2012. Et la date d’arrêt ne sera donc jamais atteinte et la fonction ne se désactivera pas. Il faut attendre le 7 janvier, qui est le premier jour de l’année en numérotation ISO des semaines (et fait donc partie de 2013), pour que ça fonctionne.

Point amusant, Apple a sûrement testé la fonction sans remarquer le bug : comme 2012 a commencé un dimanche, la semaine ISO a commencé le 2 janvier 2012, ce qui a rendu le bug peu visible. Par contre, sans correction d’Apple, il faudra attendre 2024 pour une année sans bug, la prochaine année durant laquelle le 1er janvier est un lundi.

Globalement, le bug est régulier et se corrige de lui même le premier lundi de l’année selon les tests, sans que la raison exacte soit visible, donc.

MAJ : une théorie indique que le bug viendrait du fait que le système aurait été prévu pour gérer des plages horaires en fonction des jours (ce qui serair une bonne idée) et qu’iOS ne propose pas d’interface pour ce réglage. Concrètement, la fonction attend un lundi à une heure précise pour se couper, et pas une date en particulier. Et comme le premier lundi de l’année 2013 en calendrier grégorien est le 7 janvier (et pas le 31 décembre 2012), l’arrêt de la fonction est décalé.