From madore@clipper.ens.fr Tue Feb  8 13:20:28 2000
Article: 2863 of ens.forum.informatique.os.linux
Path: eleves!not-for-mail
From: madore@clipper.ens.fr (GroTeXdieck)
Newsgroups: ens.forum.informatique.os.linux
Subject: Re: heure
Date: 8 Feb 2000 12:20:28 GMT
Lines: 203
Sender: madore@clipper.ens.fr
Message-ID: <87p1mc$5us$1@clipper.ens.fr>
References: <87nm3i$4f$1@clipper.ens.fr> <87nmsm$jm$1@clipper.ens.fr> <87nqt3$4tr$1@clipper.ens.fr>
NNTP-Posting-Host: clipper.ens.fr
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: clipper.ens.fr 950012428 6108 129.199.129.1 (8 Feb 2000 12:20:28 GMT)
X-Complaints-To: forum@clipper.ens.fr
NNTP-Posting-Date: 8 Feb 2000 12:20:28 GMT
X-Newsreader: Flrn (0.4.0 - 07/99)
X-Slashdot-Headline: IBM Announcements on Chip Design/Nanocommunications 
X-Mark: BOG
Xref: eleves ens.forum.informatique.os.linux:2863

Bon, d'abord pour l'histoire des horloges.  Il y a deux horloges, une
horloge permanente, dite horloge BIOS, horloge CMOS, ou RTC (Real-Time
Clock), trois termes inadaptés d'ailleurs, qui tourne même quand le PC
est éteint, et qui ne dépend pas du système.  L'autre, l'horloge
système, sous Linux (je ne sais pas ce que Windows fait), qui est
maintenue par le système et pas par le hard, et qui s'incrémente en
utilisant l'IRQ0, générée périodiquement (100 fois par seconde sous
Linux) par le générateur de fréquence.

Quand tu tapes « date », tu obtiens l'heure système.  Pour obtenir
l'heure CMOS, il faut taper /sbin/hwclock (ou peut-être /sbin/clock ;
ça dépend de ta version de RedHat).

L'heure système est *toujours* à UTC (le temps Universel - qui n'est
pas le temps de Londres, parce qu'à Londres, comme à Paris, il y a une
heure d'été : disons que c'est le temps de Londres en hiver).
Autrement dit, la fonction gettimeofday() ou bien time() renvoie le
nombre de secondes écoulées en temps UTC depuis le 1er janvier 1970 à
minuit temps UTC[*].  Là où le fuseau horaire intervient, c'est dans
la conversion qui en est faite par la fonction localtime() de la libc
(qui va découper le temps en nombre de seconde en année, mois, jour,
heure, minute et seconde).

Le fuseau horaire sur le système GNU[#] est réglé par le lien
symbolique /etc/localtime qui doit pointer vers un fichier de
/usr/share/zoneinfo/ (par exemple Europe/Paris pour Paris[+]).  Sur la
RedHat 6.1, ce n'est plus un lien symbolique mais une copie du fichier
(pour que l'heure soit bonne même avant que / ait été monté).

De plus, dans la RedHat 6.1 (et je ne sais plus trop si c'était le cas
avant ou non), le fichier /etc/sysconfig/clock contient une ligne
ZONE= contenant le nom de la timezone (par exemple "Europe/Paris").
Je ne sais pas quand cette ligne est utilisée, mais autant qu'elle
coïncide avec le /etc/localtime

Revenant à l'heure CMOS, il y a deux possibilités : la régler sur
l'heure locale ou la régler sur le temps universel.  La ligne UTC du
fichier /etc/sysconfig/clock sous RedHat annonce au système ce qu'on a
fait.  Si on la règle sur l'heure locale, il faudra qu'elle soit
changée d'une heure à chaque changement d'heure.  L'OS peut le faire
(que ce soit Windows ou Linux), mais c'est de la magie noire, je n'ai
aucune idée par quel procédé ça se fait, et je crains fort que ça
risque d'être fait deux fois parce que les OS n'ont pas le moyen de
communiquer entre eux.  Je ne sais pas non plus s'il est mieux, ou au
contraire pire, que la machine soit allumée au moment du changement
d'heure.

L'autre possibilité est de régler l'heure CMOS sur le temps universel.
Ce qui est logique, parce que ça veut dire que tu n'as strictement
rien à changer à cette heure au moment du changement d'heure ou si tu
emportes ton PC (p.e. un portable) dans un autre fuseau horaire.  Tu
as juste à changer l'offset que l'OS apportera à l'heure avant de te
la représenter (donc, sous GNU, le /etc/localtime).  De cette façon,
la philosophie, c'est que le Temps est quelque chose d'absolu, et que
(aux secondes intercalaires près) c'est le Temps Universel Coordonné,
et que le temps local ça ne sert que parce que toi, misérable humain,
tu es encore habitué à t'intéresser vaguement à la position du soleil
dans le ciel, donc la libc a la générosité de te dire quel est l'heure
locale là où tu es (si tu lui dis où tu es).  Mais le Système
tout-puissant, lui, n'en a rien à faire de cette heure locale, et seul
compte le Temps Universel.  (L'avantage du Temps Universel, c'est que
pour savoir le temps écoulé entre deux instants il n'y a - aux
secondes intercalaires près - qu'à faire une différence.)

Pour se convaincre de la justesse de cette vision, on notera que la
variable d'environnement TZ permet d'overrider la valeur de
/etc/localtime ; ainsi, si on tape

  TZ=US/Eastern date

(que ce soit sous GNU ou sous Solaris), on obtient l'heure sur la côte
est des États-Unis.  Preuve que le système s'en fout complètement
(l'heure système n'a pas été modifiée, évidemment), et que c'est
l'utilisateur qui décide ce qu'il veut voir.  (Après tout, si
l'ordinateur était un grand réseau distribué dans le monde entier,
l'heure locale n'aurait aucun sens ; seule compte la préférence de
l'utilisateur.)

(De même, le timestamp des fichiers dans le filesystem est à UTC, et
non à l'heure locale.  Ainsi, la valeur de TZ influence ce que tu
verras avec ls -l)

Bref, je recomande *très vivement* de mettre l'heure CMOS à UTC (donc,
concrètement, dans le BIOS, de régler celle-ci à une heure de moins en
hiver, deux heures en été, que l'heure locale à Paris).  (De toute
façon, rapidement, on ne règle plus rien par le BIOS, on règle par
NTP, et on met l'heure CMOS à jour depuis Linux.  Enfin, c'est ce que
je fais.)

Le seul problème c'est que *peut-être* Windows ne supporte pas ça.  Je
ne connais rien à Windows, donc je ne suis pas capable de te dire s'il
y a moyen de lui annoncer « l'heure CMOS est à UTC : tu dois donc
corriger toi-même *sans changer cette heure CMOS* ».  Ce serait la
moindre des choses, mais, après tout, Windows est un OS pour neuneux,
et un neuneu ne sait pas ce que c'est qu'UTC.  Supposons donc que ce
ne soit pas possible.  Peux-tu tolérer que l'heure qui te sera
affichée sous Windows soit l'heure UTC ?  Si oui, dis simplement à
Windows que tu es au fuseau UTC (ou GMT), et tout ira bien.  Si c'est
vraiment insupportable, alors tu devras mettre ton horloge CMOS au
temps local (i.e. la laisser comme elle est), mais ne dis pas que je
ne t'ai pas prévenu.  Et, accessoirement, plains-toi au service
consommateur de Micro$oft, qui n'en a rien à cirer, mais c'est pour le
principe.

Pour régler l'heure système à partir du réseau, on fait ntpdate -u
<nom d'un serveur NTP>.  Pour la régler à partir de l'heure CMOS
(comme c'est fait au boot), on fait hwclock --utc --hctosys (en
omettant le --utc si l'horloge CMOS n'est pas à UTC ; mais alors
l'heure locale doit être bien réglée sinon bobo).  Pour faire le
contraire (régler l'heure CMOS à partir de l'heure système), on fait
hwclock --utc --systohc (idem pour le --utc).

Seb in litteris <87nqt3$4tr$1@clipper.ens.fr> scripsit:
> /etc/sysconfig#cat clock 
> UTC=true
> ARC=false

Donc, tu dois mettre UTC à false puisque ton horloge CMOS est à
l'heure locale d'après ce que tu dis (à moins que tu changes d'avis).
Et rajouter

ZONE="Europe/Paris"

à la fin.  Et enfin, tu fais un

ln -s ../usr/share/zoneinfo/Europe/Paris /etc/localtime

si RedHat <=6.0 ou bien

cp -a /usr/share/zoneinfo/Europe/Paris /etc/localtime

si RedHat >=6.1.

Et normalement tout sera pour le mieux.

Quant au ARC, comme Bip l'a expliqué, tu n'y touches PAS.

>> Pour se mettre à l'heure, le plus simple est de faire un ntpdate -u
>> canon.inria.fr une fois connecté au réseau.  Éventuellement, on pourra
> 
> J'ai fait, mais je suis toujours à 20h et des poussieres, alors qu'il est
> quand meme 2h du mat'. J'ai essayé de changer le flag UTC de
> /etc/sysconfig/clock, mais ça fait la même chose. Idem pour les deux
> valeurs possibles de ARC (c'est quoi, d'ailleurs) ?

Ton horloge *est* à l'heure.  Simplement elle l'affiche dans le
mauvais fuseau (il faut lire les trois lettres qui suivent l'heure :
CET ou MET c'est pour Paris, GMT ou UTC pour UTC, et EST pour la côte
est des États-Unis).

> Ça ce serait idéal. Mais comme 
> /etc/sysconfig#man -k xntp
> xntp: nothing appropriate
> comment je fais pour deviner les parties "assez faciles à configurer" ? Y

Tu édites /etc/ntp.conf et tu y rajoutes (p.e. tout au début) la ligne

server 129.199.96.12

et ensuite tu lances le truc avec /etc/rc.d/init.d/xntpd start (tu
auras pris le soin de faire le ntpdate avant).  Si tu veux le lancer à
chaque boot, tu édites /etc/rc.d/init.d/xntpd pour que la ligne
« chkconfig » (au début, en commentaire) lise

# chkconfig: 345 55 10

et tu fais chkconfig --add xntpd

(Le fait que tu ne sois pas toujours connecté au réseau n'est pas
grave : xntpd s'en apercevra.)

Attention : je décline toute responsabilité quand au fonctionnement
peut-être anormal de xntpd si l'heure CMOS n'est pas, comme je le
conseille, à UTC (ceci était de la pure mauvaise foi).

D'autre part, tu peux éventuellement faire de temps en temps un
« hwclock --utc --systohc » (sans le --utc dans les circonstances
qu'on sait) pour que cette belle heure système, rendue très précise
par NTP, soit sauvegardée dans l'heure CMOS.  Éventuellement, tu peux
mettre ça dans un fichier /etc/cron.hourly/clock.cron pour que ça se
passe tout seul toute les heures.

> Ah. C'est quoi l'horloge systeme, l'horloge CMOS ? Pas la peine de perdre
> du temps à détailler trop les concepts ; si tu veux bien me dire comment
> faire je serai ravi.

Mais bien sûr qu'il faut détailler les concepts.  Ça serait idiot de
te dire juste « tu fais ceci ».  D'abord parce que c'est à toi de
prendre les décisions (p.e. si tu veux une horloge CMOS à UTC ou à
l'heure de Paris), pas à moi.

[*] Donc stricto sensu ce n'est pas un nombre de secondes écoulées
puisqu'il y a des secondes intercalaires qui d'après POSIX ne doivent
pas être comptées.  On peut aussi régler son horloge sur TAI, ce qui à
mon sens est plus logique.  Voir
http://www.eleves.ens.fr:8080/home/madore/misc/time.html

[#] J'écris « GNU » plutôt que « Linux » ou « GNU/Linux », parce que
Linux n'a vraiment strictement rien à voir la dedans : c'est la glibc
qui s'occupe de ça.  Sous Hurd, donc, c'est pareil.

[+] Ou right/Europe/Paris si on veut mettre son horloge système sur
TAI plutôt qu'UTC.

