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:
☾orU+263Ebefore sunrise,☼orU+263Cduring daylight,☽orU+263Dafter 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
%Gspecifier gives the same result as the%Yspecifier.The letter
"W"for "week" may surprise some people, because it introduces the number of the décade, not week.The
%uspecifier 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::Calendar::FrenchRevolutionary or https://github.com/jforget/DateTime-Calendar-FrenchRevolutionary
Date::Convert::French_Rev or https://github.com/jforget/Date-Convert-French_Rev
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.