1 ;;; cal-french.el --- calendar functions for the French Revolutionary calendar.
3 ;; Copyright (C) 1988, 1989, 1992 Free Software Foundation, Inc.
5 ;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
6 ;; Keywords: French Revolutionary calendar, calendar, diary
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is distributed in the hope that it will be useful,
11 ;; but WITHOUT ANY WARRANTY. No author or distributor
12 ;; accepts responsibility to anyone for the consequences of using it
13 ;; or for whether it serves any particular purpose or works at all,
14 ;; unless he says so in writing. Refer to the GNU Emacs General Public
15 ;; License for full details.
17 ;; Everyone is granted permission to copy, modify and redistribute
18 ;; GNU Emacs, but only under the conditions described in the
19 ;; GNU Emacs General Public License. A copy of this license is
20 ;; supposed to have been given to you along with GNU Emacs so you
21 ;; can know your rights and responsibilities. It should be in a
22 ;; file named COPYING. Among other things, the copyright notice
23 ;; and this notice must be preserved on all copies.
27 ;; This collection of functions implements the features of calendar.el and
28 ;; diary.el that deal with the French Revolutionary calendar.
30 ;; Technical details of the French Revolutionary calendrical calculations can
31 ;; be found in ``Calendrical Calculations, Part II: Three Historical
32 ;; Calendars'' by E. M. Reingold, N. Dershowitz, and S. M. Clamen,
33 ;; Report Number UIUCDCS-R-92-1743, Department of Computer Science,
34 ;; University of Illinois, April, 1992.
36 ;; Comments, corrections, and improvements should be sent to
37 ;; Edward M. Reingold Department of Computer Science
38 ;; (217) 333-6733 University of Illinois at Urbana-Champaign
39 ;; reingold@cs.uiuc.edu 1304 West Springfield Avenue
40 ;; Urbana, Illinois 61801
46 (defconst french-calendar-month-name-array
47 ["Vende'miaire" "Brumaire" "Frimaire" "Nivo^se" "Pluvio^se" "Vento^se"
48 "Germinal" "Flore'al" "Prairial" "Messidor" "Thermidor" "Fructidor"])
50 (defconst french-calendar-day-name-array
51 ["Primidi" "Duodi" "Tridi" "Quartidi" "Quintidi" "Sextidi" "Septidi"
52 "Octidi" "Nonidi" "Decadi"])
54 (defconst french-calendar-special-days-array
55 ["de la Vertu" "du Genie" "du Labour" "de la Raison" "de la Recompense"
58 (defun french-calendar-leap-year-p (year)
59 "True if YEAR is a leap year on the French Revolutionary calendar.
60 For Gregorian years 1793 to 1805, the years of actual operation of the
61 calendar, uses historical practice based on equinoxes is followed (years 3, 7,
62 and 11 were leap years; 15 and 20 would have been leap years). For later
63 years uses the proposed rule of Romme (never adopted)--leap years fall every
64 four years except century years not divisible 400 and century years that are
66 (or (memq year
'(3 7 11));; Actual practice--based on equinoxes
67 (memq year
'(15 20)) ;; Anticipated practice--based on equinoxes
68 (and (> year
20) ;; Romme's proposal--never adopted
70 (not (memq (% year
400) '(100 200 300)))
71 (not (zerop (% year
4000))))))
73 (defun french-calendar-last-day-of-month (month year
)
74 "Last day of MONTH, YEAR on the French Revolutionary calendar.
75 The 13th month is not really a month, but the 5 (6 in leap years) day period of
76 `sansculottides' at the end of the year."
79 (if (french-calendar-leap-year-p year
)
83 (defun calendar-absolute-from-french (date)
84 "Absolute date of French Revolutionary DATE.
85 The absolute date is the number of days elapsed since the (imaginary)
86 Gregorian date Sunday, December 31, 1 BC."
87 (let ((month (extract-calendar-month date
))
88 (day (extract-calendar-day date
))
89 (year (extract-calendar-year date
)))
90 (+ (* 365 (1- year
));; Days in prior years
91 ;; Leap days in prior years
93 (/ year
4);; Actual and anticipated practice (years 3, 7, 11, 15)
94 ;; Romme's proposed rule (using the Principle of Inclusion/Exclusion)
95 (+ (/ (1- year
) 4);; Luckily, there were 4 leap years before year 20
98 (- (/ (1- year
) 4000))))
99 (* 30 (1- month
));; Days in prior months this year
100 day
;; Days so far this month
101 654414)));; Days before start of calendar (September 22, 1792).
103 (defun calendar-french-from-absolute (date)
104 "Compute the French Revolutionary date (month day year) corresponding to
105 absolute DATE. The absolute date is the number of days elapsed since the
106 (imaginary) Gregorian date Sunday, December 31, 1 BC."
108 (list 0 0 0);; pre-French Revolutionary date
109 (let* ((approx (/ (- date
654414) 366));; Approximation from below.
110 (year ;; Search forward from the approximation.
112 (calendar-sum y approx
113 (>= date
(calendar-absolute-from-french (list 1 1 (1+ y
))))
115 (month ;; Search forward from Vendemiaire.
116 (1+ (calendar-sum m
1
118 (calendar-absolute-from-french
120 (french-calendar-last-day-of-month m year
)
123 (day ;; Calculate the day by subtraction.
125 (1- (calendar-absolute-from-french (list month
1 year
))))))
126 (list month day year
))))
128 (defun calendar-print-french-date ()
129 "Show the French Revolutionary calendar equivalent of the date under the
132 (let* ((french-date (calendar-french-from-absolute
133 (calendar-absolute-from-gregorian
134 (or (calendar-cursor-to-date)
135 (error "Cursor is not on a date!")))))
136 (y (extract-calendar-year french-date
))
137 (m (extract-calendar-month french-date
))
138 (d (extract-calendar-day french-date
)))
140 (message "Date is pre-French Revolution")
142 (message "Jour %s de l'Anne'e %d de la Revolution"
143 (aref french-calendar-special-days-array
(1- d
))
145 (message "Decade %s, %s de %s de l'Anne'e %d de la Revolution"
146 (make-string (1+ (/ (1- d
) 10)) ?I
)
147 (aref french-calendar-day-name-array
(%
(1- d
) 10))
148 (aref french-calendar-month-name-array
(1- m
))
151 (defun calendar-goto-french-date (date &optional noecho
)
152 "Move cursor to French Revolutionary DATE.
153 Echo French Revolutionary date unless NOECHO is t."
155 (let* ((year (calendar-read
156 "Anne'e de la Revolution (>0): "
157 '(lambda (x) (> x
0))
159 (extract-calendar-year
160 (calendar-french-from-absolute
161 (calendar-absolute-from-gregorian
162 (calendar-current-date)))))))
165 (append french-calendar-month-name-array
166 (if (french-calendar-leap-year-p year
)
168 '(lambda (x) (concat "Jour " x
))
169 french-calendar-special-days-array
)
170 (cdr;; we don't want rev. day in a non-leap yr.
173 '(lambda (x) (concat "Jour " x
))
174 french-calendar-special-days-array
)))))))
175 (completion-ignore-case t
)
179 "Mois ou Sansculottide: "
185 '(lambda (x) (capitalize (car x
)))))))
186 (decade (if (> month
12)
190 '(lambda (x) (memq x
'(1 2 3))))))
191 (day (if (> month
12)
195 '(lambda (x) (and (<= 1 x
) (<= x
10))))))
196 (month (if (> month
12) 13 month
))
197 (day (+ day
(* 10 (1- decade
)))))
198 (list (list month day year
))))
199 (calendar-goto-date (calendar-gregorian-from-absolute
200 (calendar-absolute-from-french date
)))
201 (or noecho
(calendar-print-french-date)))
203 (defun diary-french-date ()
204 "French calendar equivalent of date diary entry."
205 (let* ((french-date (calendar-french-from-absolute
206 (calendar-absolute-from-gregorian date
)))
207 (y (extract-calendar-year french-date
))
208 (m (extract-calendar-month french-date
))
209 (d (extract-calendar-day french-date
)))
212 (format "Jour %s de l'Anne'e %d de la Revolution"
213 (aref french-calendar-special-days-array
(1- d
))
215 (format "Decade %s, %s de %s de l'Anne'e %d de la Revolution"
216 (make-string (1+ (/ (1- d
) 10)) ?I
)
217 (aref french-calendar-day-name-array
(%
(1- d
) 10))
218 (aref french-calendar-month-name-array
(1- m
))
221 (provide 'cal-french
)
223 ;;; cal-french.el ends here