notes-fr

# -*- encoding: utf-8; indent-tabs-mode: nil -*-

Notes du concepteur

Préliminaire

Ce texte détaille les notes de conception pour le module de calendrier hébraïque. Une version complète figure dans la distribution Perl 6 pour le module de calendrier républicain.

Il est préférable de faire référence à des exemples plutôt que d'utiliser des données génériques. Pour ce faire, j'utiliserai les dates suivantes (le 14 juillet de cette année) :

Dimanche 14 juillet 2019
  Sunday 14 July 2019
  11 Tammuz 5779
  11 Dhu al-Qada 1440
  Sextidi 26 Messidor 227
  13.0.6.11.16, 8 Cib, 4 Xul

Buts

Les modules de calendrier doivent tendre vers ces buts contradictoires :

  • Un utilisateur peut décider de charger autant de modules qu'il souhaite. Il peut tous les utiliser ou n'utiliser aucun module outre le module central Date.

  • Limiter autant que possible la duplication de code. Plutôt DRY (Don't Repeat Yourself, Ne vous répétez pas) que WET (Write Everything Twice, Tout écrire deux fois).

  • Ne pas toucher aux modules standards, y compris Date.

Première idée : des rôles partout

Ma première idée était d'utiliser de manière intensive la nouveauté de Perl 6 en programmation objet, les rôles. Seul le calendrier grégorien serait implémenté en tant que classe, les autres calendriers seraient des rôles accolés à la classe Date. Par exemple :

my Date $quatorze-juillet does Date::Calendar::Hebrew
                            does Date::Calendar::Hijri
                            does Date::Calendar::FrenchRevolutionary
                            does Date::Calendar::Mayan
            .= new(year => 2019, month => 7, day => 14);

Le premier problème est le conflit de nom entre les méthodes des divers rôles. Si nous codons :

say $quatorze-juillet.month-name

obtiendrons-nous Tammuz, Dhu al-Qada ou Messidor ? D'accord, il suffit de lire la page 226 et les suivantes de Learning Perl 6 et l'on apprend que l'on peut écrire :

say $quatorze-juillet.month-name( Date::Calendar::FrenchRevolutionary );
  # → Messidor
  say $quatorze-juillet.month-name( Date::Calendar::Hebrew );
  # → Tammuz

Mais c'est laborieux.

Le second problème est que le concept de date n'est pas le même d'une civilisation à l'autre. Le calendrier grégorien et le calendrier républicain utilisent des dates de minuit à minuit, alors que le calendrier hébraïque, le calendrier islamique et plusieurs autres utilisent des dates du coucher du soleil au coucher suivant. Le Julian Day Number (à ne pas confondre avec le calendrier julien) se base sur des dates de midi à midi. Et il n'est pas exclu que d'autres calendriers définissent les dates comme s'étendant du lever du soleil au lever suivant du soleil. On peut donc assimiler le 14 juillet 2019 au 26 Messidor 227, mais pas au 11 Tammuz 5579. Habituellement, les programmes de conversion s'en tirent en écrivant dans la documentation utilisateur que la conversion 14 juillet 2019 → 11 Tammuz 5779 est valide avant le coucher du soleil. Mais il pourrait y avoir un programmeur un peu plus aventureux qui coderait deux routines de conversion ou qui ajouterait un paramètre « moment de la journée » à sa routine de conversion pour obtenir soit :

14 juillet 2019 → 11 Tammuz 5779

soit :

14 juillet 2019 → 12 Tammuz 5779

En implémentant le calendrier hébraïque en tant que rôle affecté au calendrier grégorien, cette possibilité n'existerait plus. En implémentant le calendrier hébraïque en tant que classe séparée, la possibilité reste ouverte. Il reste des problèmes à résoudre dans ce cas, mais au moins nous ne sommes pas bloqués.

Pendant que j'écrivais le module de calendrier républicain, j'ai trouvé un argument supplémentaire. L'utilisation d'années négatives (ou av J.C.) est justifiée pour le calendrier julien et le calendrier grégorien (même en considérant que le calendrier grégorien a pris effet le 15 octobre 1582), ce n'est pas le cas pour les autres calendriers. Ainsi, le calendrier républicain a pour origine des temps le 22 septembre 1792 et il n'y a alors aucune raison d'autoriser l'objet 21 septembre 1792 à utiliser les méthodes du rôle « calendrier républicain ».

La solution est donc : un calendrier = une classe.

Examen du module standard Date

Je n'avais pas l'intention de traiter les heures (décimales ou 24×60×60) donc j'ai seulement regardé Date, pas DateTime.

Échelle de temps en jours

La première différence entre le module Date de Perl 6 et le module DateTime de Perl 5 est que Perl 6 utilise le MJD (Modified Julian Day Number) au lieu d'utiliser le Rata Die. Cela me va très bien.

Immutabilité

Une deuxième différence avec le module DateTime de Perl 5, c'est que les dates ne sont pas modifiables. Et pourquoi pas ? Cela ne me dérange pas. Donc les dates dans Date::Calendar::xxx ne seront pas modifiables. Voir cependant ci-dessous le cas d'un calendrier avec plusieurs langues.

Affichage en langage naturel

Une autre différence avec Perl 5, c'est qu'il n'y a rien de prévu en standard pour afficher du langage naturel, essentiellement les noms des jours et les noms des mois. Peut-être a-t-on estimé que l'utilisation principale du module Date serait la constitution d'horaires ou la planification de tâches, ce qui ne nécessite que les valeurs numériques des jours et des mois, pas les noms en clair.

Et si vous avez quand même besoin des noms en clair, vous pouvez installer et utiliser Date::Names disponible sur zef ou CPAN6.

Calendrier simple

Comme exemple de calendrier simple, je prendrai le calendrier hébraïque. La simplicité concerne l'architecture du module, pas les algorithmes de conversion. Il n'y a pas de variante pour le calendrier hébraïque, donc de ce point de vue c'est un calendrier simple.

Calendrier avec une seule langue

À mon avis, si quelqu'un utilise un module de calendrier autre que grégorien, c'est pour afficher la date convertie, pas pour faire des calculs de délai ou planifier des tâches. Les noms en clair seront dans un module séparé, mais ce module séparé fera partie intégrante de la distribution. Ainsi, la distribution Date::Calendar::Hebrew incluera à la fois le module Date::Calendar::Hebrew et le module Date::Calendar::Hebrew::Names.

En résumé, nous avons dans ce cas :

classe   Date::Calendar::Hebrew
  routines Date::Calendar::Hebrew::Names

Calendrier avec plusieurs langues

Si les noms sont disponibles dans plusieurs langages pour un même calendrier, je peux dans certains cas tout mettre dans un même module Date::Calendar::xxx::Names, mécanisme et données, ou bien je peux scinder cela en mettant le mécanisme dans Date::Calendar::xxx::Names et les données dans Date::Calendar::xxx::Names::en, Date::Calendar::xxx::Names::fr, Date::Calendar::xxx::Names::it et ainsi de suite. Tout dépendra de la taille.

Pour le calendrier hébraïque, avec l'hébreu, le yiddish et l'araméen, cela donnerait :

classe   Date::Calendar::Hebrew
  routines Date::Calendar::Hebrew::Names
  routines Date::Calendar::Hebrew::Names::he
  routines Date::Calendar::Hebrew::Names::yi
  routines Date::Calendar::Hebrew::Names::arc

(Désolé, l'araméen n'a pas de code ISO 639 à deux caractères, j'ai dû me rabattre sur le code à trois caractères.)

Un autre point est que dans le cas où plusieurs langages sont disponibles, l'objet Date::Calendar::xxx aura un attribut locale et l'utilisateur pourra alors faire varier cet attribut pour afficher une même date dans plusieurs langues. Même si les attributs année, mois et jour sont invariants, l'attribut locale sera modifiable. Et l'objet ne sera plus totalement « immutable ». En prenant un exemple tiré du calendrier républicain, changer « Sextidi 26 Messidor 227, jour de la sauge » en « Sixday 26 Reapidor 227, day of sage » est une modification cosmétique et superficielle de l'instance de date, changer « Sextidi 26 Messidor 227 , jour de la sauge» en « Septidi 27 Messidor 227, jour de l'ail » est une modification profonde et essentielle de l'instance.

Calendriers avec variantes

Dans le but de rester simple, le présent texte n'ira pas plus loin et laissera de côté le cas plus compliqué des calendriers avec variantes. Veuillez vous référer à la distribution Date::Calendar::FrenchRevolutionary qui contient la version complète du présent texte.

Licence

Texte diffusé sous la licence CC-BY-SA : Creative Commons avec attribution, partage dans les mêmes conditions.

Date::Calendar::Hebrew v0.1.0

Conversions from / to the Hebrew calendar

Authors

  • Jean Forget

License

Artistic-2.0

Dependencies

List::MoreUtilsDate::Calendar::Strftime

Test Dependencies

Provides

  • Date::Calendar::Hebrew
  • Date::Calendar::Hebrew::Names

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.