Une petite seconde de plus en juin…

Publié par cpb
Juin 28 2012

Leap-SecondVous le savez peut-être, l’IERS (International Earth Rotation and Reference Systems Service) a décidé d’ajouter une seconde intercalaire (leap second) à la fin de la dernière minute du mois de juin. Ces secondes, que l’on insère tous les deux ou trois ans à la fin du mois de décembre ou de juin (la dernière date du 31/12/2008) servent à ajuster l’heure officielle avec la rotation de la terre. Cela à commencé il y a quarante ans, le 30 juin 1972.

Cette seconde est ajoutée au même instant dans le monde entier. Il y aura donc une seconde numérotée 23:59:60 le 30/06/2012 suivant l’heure UTC, ce qui se traduira en France par une heure 01:59:60 le dimanche 01/07/2012.

Inutile de guetter votre montre numérique, votre four à micro-ondes ou votre réveil-matin, ils n’en tiendront très probablement pas compte (quand à la Freebox… tout est possible !). Votre PC sous Linux en revanche devrait normalement être capable d’afficher la seconde intercalaire, pourvu qu’il soit correctement configuré. Je ne traite pas de la configuration d’un serveur NTP, mais simplement des commandes utilisateur courantes.

Essayons tout d’abord de demander à la commande date d’afficher l’heure locale correspondant au timestamp Unix (nombre de secondes écoulées depuis le 01/01/1970) aux alentours de cette seconde. J’ai bien sûr tâtonné un peu pour trouver la valeur.

$ date -d @1341100798
dimanche 1 juillet 2012, 01:59:58 (UTC+0200)
$ date -d @1341100799
dimanche 1 juillet 2012, 01:59:59 (UTC+0200)
$ date -d @1341100800
dimanche 1 juillet 2012, 02:00:00 (UTC+0200)
$ date -d @1341100801
dimanche 1 juillet 2012, 02:00:01 (UTC+0200)
$

Pas de seconde intercalaire en vue. Mon poste de travail est basé sur une distribution Ubuntu 12.04 standard. Il n’y a visiblement pas de support pour les leap seconds. C’est traditionnellement le cas, le timestamp est calculé sans tenir compte de ces secondes (ce qui fait qu’il est décalé d’une vingtaine de secondes par rapport à une horloge qui aurait réellement compté les secondes écoulées depuis le 01/01/1970).

Rien ne nous interdit toutefois d’ajouter un petit support pour cette seconde intercalaire à venir.

Compilation d’un fichier timezone

En réalité, l’interprétation de l’heure absolue (le timestamp) dépend d’un certain nombre de règles (le fuseau horaire, l’heure d’été, etc.) qui sont configurées dans des fichiers timezone. Ces fichiers se trouvent dans /usr/share/zoneinfo.

Si vous employez comme moi le fuseau Europe/Paris (décrit dans le fichier /etc/timezone), l’heure sera interprétée suivant les règles décrites dans /usr/share/zoneinfo/Europe/Paris.

Or ce fichier ne connait vraisemblablement pas la seconde intercalaire du mois de juin. Nous pouvons l’y ajouter. Malheureusement, le fichier zoneinfo est un fichier binaire, compilé à partir d’une description en clair des règles d’interprétation, ceci grâce à l’utilitaire zic.

Pour obtenir le fichier de règles à compiler, on peut télécharger les sources de la Glibc et se rendre dans son sous-répertoire timezone/. On y trouve entre autre le fichier europe ainsi qu’un fichier leapseconds. Celui-ci n’est pas pris en compte pour générer les fichiers zoneinfo d’Ubuntu.

J’ai créé un petit fichier leap-second qui ne contient que notre seconde intercalaire à venir.

Leap	2012	Jun	30	23:59:60	+	S

Je vais simplement compiler le fichier europe avec zic, en lui demandant de créer les fichiers dans le répertoire courant et non pas dans /usr/share/zoneinfo.

$ ls
europe  leap-second
$ /usr/sbin/zic -L leap-second -d . europe 
$ ls
Africa  America  Arctic  Asia  Atlantic  CET  EET  europe  Europe  leap-second  MET  WET
$ ls -l Europe/Paris 
-rw-r--r-- 1 cpb cpb 2965 juin  28 15:10 Europe/Paris
$

Installation

Nous allons remplacer le fichier Europe/Paris du système par le nôtre (après avoir sauvegardé le précédent).

$ sudo cp /usr/share/zoneinfo/Europe/Paris /usr/share/zoneinfo/Europe/Paris-Bkup
$ sudo cp ./Europe/Paris /usr/share/zoneinfo/Europe/Paris
$

Il faut alors utiliser le menu système pour fixer à nouveau le fuseau horaire. Ceci a pour effet de copier le fichier zoneinfo correspondant (celui que nous venons d’installer) dans /etc/localtime. C’est ce dernier fichier qui est en effet consulté par la commande date, sauf si on fixe explicitement auparavant la variable d’environnement TZ.

Essai

$ date -d @1341100798
dimanche 1 juillet 2012, 01:59:58 (UTC+0200)
$ date -d @1341100799
dimanche 1 juillet 2012, 01:59:59 (UTC+0200)
$ date -d @1341100800
dimanche 1 juillet 2012, 01:59:60 (UTC+0200)
$ date -d @1341100801
dimanche 1 juillet 2012, 02:00:00 (UTC+0200)
$

Et oui, ça fonctionne, nous avons bien une heure 01:59:60.

Notez que si l’on fixe la variable TZ pour utiliser l’ancien fichier zoneinfo, cela donne:

$ export TZ=Europe/Paris-Bkup
$ date -d @1341100799
dimanche 1 juillet 2012, 01:59:59 (UTC+0200)
$ date -d @1341100800
dimanche 1 juillet 2012, 02:00:00 (UTC+0200)
$ date -d @1341100801
dimanche 1 juillet 2012, 02:00:01 (UTC+0200)
$

Conclusion

Je ne pense pas être devant mon PC à deux heures du matin dimanche, mais si c’est le cas, je ferai une capture d’écran, c’est promis.

PS: Si vous avez l’occasion d’observer cette seconde intermédiaire sur une set-top-box, un récepteur radio ou GPS, un serveur NTP, etc. cela m’intéresse de savoir s’ils ont affiché 01:59:60 comme nous l’avons vu.

 

Une réponse

  1. Olivier Berger dit :

    Ne faudrait-il pas filer un bug sur launchpad, alors ?

URL de trackback pour cette page