FrenchRevolutionary

NAME

Date::Calendar::FrenchRevolutionary - Conversions from / to the French Revolutionary calendar

SYNOPSIS

Converting from a Gregorian date to a French Revolutionary date


use Date::Calendar::FrenchRevolutionary;
my Date $Bonaparte's-coup-gr;
my Date::Calendar::FrenchRevolutionary
        $Bonaparte's-coup-fr;

$Bonaparte's-coup-gr .= new(1799, 11, 9);
$Bonaparte's-coup-fr .= new-from-date($Bonaparte's-coup-gr);

say $Bonaparte's-coup-fr;
# ---> "0008-02-18" for 18 Brumaire VIII
say "{.day-name} {.day} {.month-name} {.year} {.feast-long}" with  $Bonaparte's-coup-fr;
# ---> "Octidi 18 Brumaire 8 jour de la dentelaire"
say $Bonaparte's-coup-fr.strftime("%Y-%m-%d");
# ---> "0008-02-18" for 18 Brumaire VIII

Converting from a French Revolutionary date to a Gregorian date


use Date::Calendar::FrenchRevolutionary;
my  Date::Calendar::FrenchRevolutionary
        $Robespierre's-downfall-fr;
my Date $Robespierre's-downfall-gr;

$Robespierre's-downfall-fr .= new(year => 2, month => 11, day => 9);
$Robespierre's-downfall-gr =  $Robespierre's-downfall-fr.to-date;

say $Robespierre's-downfall-gr;
# ---> "1794-07-27" for 27th July 1794

Conversion with a calendar which defines days as sunset to sunset


use Date::Calendar::Strftime;
use Date::Calendar::Hebrew;
use Date::Calendar::FrenchRevolutionary;
my  Date::Calendar::FrenchRevolutionary $d-fr;
my  Date::Calendar::Hebrew              $d-he;

$d-fr .= new(year => 233, month => 2, day => 23, daypart => before-sunrise());
$d-he .= new-from-date($d-fr);
say $d-he.strftime("%A %d %B %Y");
# ---> "Yom Reviʻi 12 Heshvan 5785"

$d-fr .= new(year => 233, month => 2, day => 23, daypart => daylight());
$d-he .= new-from-date($d-fr);
say $d-he.strftime("%A %d %B %Y");
# ---> "Yom Reviʻi 12 Heshvan 5785" again

$d-fr .= new(year => 233, month => 2, day => 23, daypart => after-sunset());
$d-he .= new-from-date($d-fr);
say $d-he.strftime("%A %d %B %Y");
# ---> "Yom Chamishi 13 Heshvan 5785" instead of "Yom Reviʻi 12 Heshvan 5785"

DESCRIPTION

Date::Calendar::FrenchRevolutionary is a class representing dates in the French Revolutionary calendar. It allows you to convert a Gregorian date into a French Revolutionary date or the other way.

The Revolutionary calendar was in use in France from 24 November 1793 (4 Frimaire II) to 31 December 1805 (10 Nivôse XIV). The modules in this distribution extend the calendar to the present and to a few centuries in the future, not limiting to Gregorian year 1805.

This new calendar was an attempt to apply the decimal rule (the basis of the metric system) to the calendar. Therefore, the week disappeared, replaced by the décade, a 10-day period. In addition, all months have exactly 3 décades, no more, no less.

Since 12 months of 30 days each do not make a full year (365.24 days), there are 5 or 6 additional days at the end of a year. These days are called "Sans-culottides", named after a political faction, but we often find the phrase "jours complémentaires" (additional days). These days do not belong to any month, but for programming purposes, it is convenient to consider they form a 13th month.

At first, the year was beginning on the equinox of autumn, for two reasons. First, the republic had been established on 22 September 1792, which happened to be the equinox, and second, the equinox was a symbol for equality, the day and the night lasting exactly 12 hours each. It was therefore in tune with the republic's motto "Liberty, Equality, Fraternity". But it was not practical, so Romme proposed a leap year rule similar to the Gregorian calendar rule.

The distribution contains two other classes, one where there was no reform and the automn equinox rule stayed in effect, another where the arithmetic rule was established since the beginning of the calendar.

METHODS

Constructors

new

Create a French Revolutionary date by giving the year, month and day numbers and optionally the locale and the day part.

new-from-date

Build a French Revolutionary date by cloning an object from another class. This other class can be the core class Date or any Date::Calendar::xxx class with a daycount method and hopefully a daypart method.

new-from-daycount

Build a French Revolutionary date from the Modified Julian Day number and from the daypart parameter (optional, defaults do daylight).

Accessors

gist

Gives a short string representing the date, in YYYY-MM-DD format.

year, month, day

The numbers defining the date.

daypart

A number indicating which part of the day. This number should be filled and compared with the following subroutines, with self-documenting names:

  • before-sunrise()

  • daylight()

  • after-sunset()

locale

The locale which controls the month names, the day names and the feasts. For the moment, only the French locale 'fr' and the English locale 'en' are available.

This attribute is rewriteable, unlike the year, the month, the day and the day part.

month-name

The month of the date, as a string. This depends on the date's current locale.

month-abbr

The abbreviated month of the date.

day-name

The name of the day within the décade (ten-day period). It depends on the date's current locale.

day-abbr

The abbreviated day of the date.

feast, feast-long, feast-caps

The name of the feast of the day, according to the date's current locale.

While the feast method gives the feast unadorned: "safran" or "saffron", the feast-long method adds a prefix: "jour du safran" or "day of saffron". In addition, the feast-caps method use titlecase for the prefix and the feast: "Jour du Safran" or "Day of Saffron".

feast       safran           saffron
  feast-long  jour du safran   day of saffron
  feast-caps  Jour du Safran   Day of Saffron

daycount

The Modified Julian Day Number (a day-only scheme based on 17 November 1858).

day-of-year

How many days since the beginning of the year. 1 to 365 on normal years, 1 to 366 on leap years.

day-of-décade

The day of the décade, as a number (1 for Primidi, 10 for Décadi).

décade-number

The number of the décade within the year, 1 to 31.

strftime

This method is very similar to the homonymous functions you can find in several languages (C, shell, etc). It also takes some ideas from printf-similar functions. For example


$df.strftime("%04d blah blah blah %-25B")

will give the day number padded on the left with 2 or 3 zeroes to produce a 4-digit substring, plus the substring " blah blah blah ", plus the month name, padded on the right with enough spaces to produce a 25-char substring. Thus, the whole string will be at least 42 chars long. By the way, you can drop the "at least" mention, because the longest month name is 15-char long, so the padding will always occur and will always include at least 10 spaces.

The list of strftime specifiers is given below.

Other Methods

to-date

Clones the date into a core class Date object or some Date::Calendar::xxx compatible calendar class. The target class name is given as a positional parameter. This parameter is optional, the default value is "Date" for the Gregorian calendar.

To convert a date from a calendar to another, you have two conversion styles, a "push" conversion and a "pull" conversion. For example, while converting from the astronomical date "1 Vendémiaire IV" to the arithmetic variant, you can code:


use Date::Calendar::FrenchRevolutionary::Astronomical;
use Date::Calendar::FrenchRevolutionary::Arithmetic;

my  Date::Calendar::FrenchRevolutionary::Astronomical $d-orig;
my  Date::Calendar::FrenchRevolutionary::Arithmetic   $d-dest-push;
my  Date::Calendar::FrenchRevolutionary::Arithmetic   $d-dest-pull;

$d-orig .= new(year  => 4
             , month => 1
             , day   => 1);
$d-dest-push  = $d-orig.to-date("Date::Calendar::FrenchRevolutionary::Arithmetic");
$d-dest-pull .= new-from-date($d-orig);
say $d-orig, ' ', $d-dest-push, ' ', $d-dest-pull;
# --> "0004-01-01 0004-01-02 0004-01-02"

When converting from the core class Date, use the pull style. When converting to the core class Date, use the push style. When converting from any class other than the core class Date to any other class other than the core class Date, use the style you prefer.

Note: the class Date::Calendar::Gregorian offers the same API as the other Class::Calendar::xxx classes, including the choice between the push style and the pull style. And it derives from the core class Date, so you also have all the methods of the core class.

Even if both calendars use a locale attribute, when a date is created by the conversion of another date, it is created with the default locale. If you want the locale to be transmitted in the conversion, you should add a line such as:


$d-dest-pull.locale = $d-orig.locale;

strftime specifiers

A strftime specifier consists of:

  • A percent sign,

  • An optional minus sign, to indicate on which side the padding occurs. If the minus sign is present, the value is aligned to the left and the padding spaces are added to the right. If it is not there, the value is aligned to the right and the padding chars (spaces or zeroes) are added to the left.

  • An optional zero digit, to choose the padding char for right-aligned values. If the zero char is present, padding is done with zeroes. Else, it is done wih spaces.

  • An optional length, which specifies the minimum length of the result substring.

  • An optional "E" or "O" modifier. On some older UNIX system, these were used to give the extended or localized version of the date attribute. Here, they rather give alternate variants of the date attribute.

  • A mandatory type code.

The allowed type codes are:

%a

The abbreviated day of décade name.

%A

The full day of décade name.

%b

The abbreviated month name, or 'S-C' for additional days (abbreviation of Sans-culottide, another name for these days).

%B

The full month name.

%c

The date-time, using the default format, as defined by the current locale.

%d

The day of the month as a decimal number (range 01 to 30).

%e

Like %d, the day of the month as a decimal number, but a leading zero is replaced by a space.

%f

The month as a decimal number (1 to 13). Unlike %m, a leading zero is replaced by a space.

%F

Equivalent to %Y-%m-%d (the ISO 8601 date format)

%G

The year as a decimal number. Strictly similar to %L and %Y.

%j

The day of the year as a decimal number (range 001 to 366).

%Ej

The feast for the day, in long format ("jour de la pomme de terre"). Also available as %*.

%EJ

The feast for the day, in capitalised long format ("Jour de la Pomme de terre").

%Oj

The feast for the day, in short format ("pomme de terre").

%L

The year as a decimal number. Strictly similar to %G and %Y.

Note: this specifier is deprecated in Date::Calendar::Strftime version 0.0.4, released in 2024. It will be removed in 2026.

%m

The month as a two-digit decimal number (range 01 to 13), including a leading zero if necessary.

%n

A newline character.

%Ep

Gives a 1-char string representing the day part:

  • ☾ or U+263E before sunrise,

  • ☼ or U+263C during daylight,

  • ☽ or U+263D after sunset.

Rationale: in C or in other programming languages, when strftime deals with a date-time object, the day is split into two parts, before noon and after noon. The %p specifier reflects this by giving a "AM" or "PM" string.

The 3-part splitting in the Date::Calendar::xxx may be considered as an alternate splitting of a day. To reflect this in strftime, we use an alternate version of %p, therefore %Ep.

%t

A tab character.

%u

The day number within the décade, 1 to 10.

This allows to print a date similar to the so-called ISO date for Gregorian, by using the format string "%G-W%V-%u". Some caveats:

  • Since the décades are synchronised with the years, and even with the months, the %G specifier gives the same result as the %Y specifier.

  • The letter "W" for "week" may surprise some people, because it introduces the number of the décade, not week.

  • The %u specifier gives a 2-char result for "Décadi". Beware if you sort the dates with an alphabetic sort on the ISO date strings, or if you use a fixed-width font in order to maintain vertical alignment in a list of dates.

%V

The décade number within the year.

%Y

The year as a decimal number. Strictly similar to %G and %L.

%Ey

The year as a lowercase Roman number.

%EY

The year as a uppercase Roman number, which is the traditional way to write years when using the French Revolutionary calendar.

%*

The feast for the day, in long format ("jour de la pomme de terre"). Also available as %Ej.

%%

A literal `%' character.

PROBLEMS AND KNOWN BUGS

About the astronomical variant: the conversion values have been computed with an algorithm implemented in Common Lisp on a span covering six millenia. This is a problem, because the algorithm is not valid over this whole period. But I have no idea when the common Lisp program becomes inaccurate and generates errors. As a pure guesswork, I will suppose it will be rather accurate during five centuries or so.

Security issues

As explained in the Date::Calendar::Strftime documentation, please ensure that format-string passed to strftime comes from a trusted source. Failing that, the untrusted source can include a outrageous length in a strftime specifier and this will drain your PC's RAM very fast.

Relations with :ver<0.0.x> classes and with core class Date

Version 0.1.0 (and API 1) was introduced to ease the conversions with other calendars in which the day is defined as sunset-to-sunset. If all Date::Calendar::xxx classes use version 0.1.x and API 1, the conversions will be correct. But if some Date::Calendar::xxx classes use version 0.0.x and API 0, there might be problems.

A date from a 0.0.x class has no daypart attribute. But when "seen" from a 0.1.x class, the 0.0.x date seems to have a daypart attribute equal to daylight. When converted from a 0.1.x class to a 0.0.x class, the date may just shift from after-sunset (or before-sunrise) to daylight, or it may shift to the daylight part of the prior (or next) date. This means that a roundtrip with cascade conversions may give the starting date, or it may give the date prior or after the starting date.

If you install <Date::Calendar::FrenchRevolutionary:ver<0.1.0>>, why would you refrain from upgrading other Date::Calendar::xxxx classes? So actually, this issue applies mainly to the core class Date, because you may prefer avoiding the installation of Date::Calendar::Gregorian.

Time

This module and the Date::Calendar::xxx associated modules are still date modules, they are not date-time modules. The user has to give the daypart attribute as a value among before-sunrise, daylight or after-sunset. There is no provision to give a HHMMSS time and convert it to a daypart parameter.

SEE ALSO

Raku Software

Date::Calendar::Strftime or https://github.com/jforget/raku-Date-Calendar-Strftime

Date::Calendar::Gregorian or https://github.com/jforget/raku-Date-Calendar-Gregorian

Date::Calendar::Julian or https://github.com/jforget/raku-Date-Calendar-Julian

Date::Calendar::Hebrew or https://github.com/jforget/raku-Date-Calendar-Hebrew

Date::Calendar::CopticEthiopic or https://github.com/jforget/raku-Date-Calendar-CopticEthiopic

Date::Calendar::MayaAztec or https://github.com/jforget/raku-Date-Calendar-MayaAztec

Date::Calendar::Hijri or https://github.com/jforget/raku-Date-Calendar-Hijri

Date::Calendar::Persian or https://github.com/jforget/raku-Date-Calendar-Persian

Date::Calendar::Bahai or https://github.com/jforget/raku-Date-Calendar-Bahai

Perl 5 Software

DateTime

DateTime::Calendar::FrenchRevolutionary or https://github.com/jforget/DateTime-Calendar-FrenchRevolutionary

Date::Convert::French_Rev or https://github.com/jforget/Date-Convert-French_Rev

Date::Converter

Other Software

date(1), strftime(3)

calendar/cal-french.el in emacs-21.2 or later or xemacs 21.1.8, forked in https://github.com/jforget/emacs-lisp-cal-french

https://www.gnu.org/software/apl/Bits_and_Pieces/calfr.apl.html or https://github.com/jforget/apl-calendar-french

https://www.hpcalc.org/details/7309 or https://github.com/jforget/hp48-hp50-French-Revolutionary-calendar

https://github.com/jforget/hp41-calfr

CALENDRICA 4.0 -- Common Lisp, which can be download in the "Resources" section of https://www.cambridge.org/us/academic/subjects/computer-science/computing-general-interest/calendrical-calculations-ultimate-edition-4th-edition?format=PB&isbn=9781107683167

French Calendar for Android at https://f-droid.org/packages/ca.rmen.android.frenchcalendar/ or https://github.com/caarmen/FRCAndroidWidget and https://github.com/caarmen/french-revolutionary-calendar

Thermidor for Android at https://github.com/jhbadger/Thermidor-Android

A Ruby program at https://github.com/jhbadger/FrenchRevCal-ruby

Books

Quid 2006, M and D Frémy, publ. Robert Laffont, page 341.

Agenda Républicain 197 (1988/89), publ. Syros Alternatives

Any French schoolbook about the French Revolution

The French Revolution, Thomas Carlyle, Oxford University Press

Calendrical Calculations (Third Edition) by Nachum Dershowitz and Edward M. Reingold, Cambridge University Press, see http://www.calendarists.com or https://www.cambridge.org/us/academic/subjects/computer-science/computing-general-interest/calendrical-calculations-ultimate-edition-4th-edition?format=PB&isbn=9781107683167.

Internet

https://github.com/houseabsolute/DateTime.pm/wiki

http://www.faqs.org/faqs/calendars/faq/part3/

http://datetime.mongueurs.net/

https://en.wikipedia.org/wiki/French_Republican_Calendar

https://fr.wikipedia.org/wiki/Calendrier_républicain

https://archive.org/details/decretdelaconven00fran_40

"Décret du 4 frimaire, an II (24 novembre 1793) sur l'ère, le commencement et l'organisation de l'année et sur les noms des jours et des mois"

https://archive.org/details/decretdelaconven00fran_41

Same text, with a slightly different typography.

https://purl.stanford.edu/dx068ky1531

"Archives parlementaires de 1789 à 1860: recueil complet des débats législatifs & politiques des Chambres françaises", J. Madival and E. Laurent, et. al., eds, Librairie administrative de P. Dupont, Paris, 1912.

Starting with page 6, this document includes the same text as the previous links, with a much improved typography. Especially, all the "long s" letters have been replaced by short s. Also interesting is the text following the decree, page 21 and following: "Annuaire ou calendrier pour la seconde année de la République française, annexe du décret du 4 frimaire, an II (24 novembre 1793) sur l'ère, le commencement et l'organisation de l'année et sur les noms des jours et des mois". In the remarks above, it is refered as [Annexe].

https://gallica.bnf.fr/ark:/12148/bpt6k48746z

[Fabre] "Rapport fait à la Convention nationale dans la séance du 3 du second mois de la seconde année de la République française, au nom de la Commission chargée de la confection du calendrier", Philippe-François-Nazaire Fabre d'Églantine, Imprimerie nationale, Paris, 1793

https://gallica.bnf.fr/ark:/12148/bpt6k49016b

[Annuaire] "Annuaire du cultivateur, pour la troisième année de la République : présenté le 30 pluviôse de l'an II à la Convention nationale, qui en a décrété l'impression et l'envoi, pour servir aux écoles de la République", Gilbert Romme, Imprimerie nationale des lois, Paris, 1794-1795

https://gallica.bnf.fr/ark:/12148/bpt6k43978x

"Calendrier militaire, ou tableau sommaire des victoires remportées par les Armées de la République française, depuis sa fondation (22 septembre 1792), jusqu'au 9 floréal an 7, époque de la rupture du Congrès de Rastadt et de la reprise des hostilités" Moutardier, Paris, An VIII de la République française.

AUTHOR

Jean Forget <J2N-FORGET at orange dot fr>

THANKS

Many thanks to all those who were involved in Raku (formerly Perl 6), Rakudo and Rakudo-Star.

Many thanks to Andrew, Laurent, brian and Moritz for writing books that helped me learn Raku.

And some additional thanks to Laurent for his help, even if I did not apply all his advices.

Many thanks to Gérald, for making a huge documentation research and shairing it with me.

SUPPORT

You can send me a mail using the address above. Please be sure to include a subject sufficiently clear and sufficiently specific to be green-flagged by my spam filter.

Or you can send a pull request to the Github repository for this module.

COPYRIGHT AND LICENSE

Copyright (c) 2019, 2020, 2024 Jean Forget, all rights reserved

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.

Date::Calendar::FrenchRevolutionary v0.1.0

Conversions from / to the French Revolutionary calendar

Authors

  • Jean Forget

License

Artistic-2.0

Dependencies

Date::Calendar::Strftime

Test Dependencies

Provides

  • Date::Calendar::FrenchRevolutionary
  • Date::Calendar::FrenchRevolutionary::Arithmetic
  • Date::Calendar::FrenchRevolutionary::Astronomical
  • Date::Calendar::FrenchRevolutionary::Common
  • Date::Calendar::FrenchRevolutionary::Names

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

Built with Podlite — the markup and publishing tools behind this site.