1 : /* $selId: french.c,v 2.0 1995/10/24 01:13:06 lees Exp $
2 : * Copyright 1993-1995, Scott E. Lee, all rights reserved.
3 : * Permission granted to use, copy, modify, distribute and sell so long as
4 : * the above copyright and this permission statement are retained in all
5 : * copies. THERE IS NO WARRANTY - USE AT YOUR OWN RISK.
6 : */
7 :
8 : /**************************************************************************
9 : *
10 : * These are the externally visible components of this file:
11 : *
12 : * void
13 : * SdnToFrench(
14 : * long int sdn,
15 : * int *pYear,
16 : * int *pMonth,
17 : * int *pDay);
18 : *
19 : * Convert a SDN to a French republican calendar date. If the input SDN is
20 : * before the first day of year 1 or after the last day of year 14, the
21 : * three output values will all be set to zero, otherwise *pYear will be in
22 : * the range 1 to 14 inclusive; *pMonth will be in the range 1 to 13
23 : * inclusive; *pDay will be in the range 1 to 30 inclusive. If *pMonth is
24 : * 13, the SDN represents one of the holidays at the end of the year and
25 : * *pDay will be in the range 1 to 6 inclusive.
26 : *
27 : * long int
28 : * FrenchToSdn(
29 : * int year,
30 : * int month,
31 : * int day);
32 : *
33 : * Convert a French republican calendar date to a SDN. Zero is returned
34 : * when the input date is detected as invalid or out of the supported
35 : * range. The return value will be > 0 for all valid, supported dates, but
36 : * there are some invalid dates that will return a positive value. To
37 : * verify that a date is valid, convert it to SDN and then back and compare
38 : * with the original.
39 : *
40 : * char *FrenchMonthName[14];
41 : *
42 : * Convert a French republican month number (1 to 13) to the name of the
43 : * French republican month (null terminated). An index of 13 (for the
44 : * "extra" days at the end of the year) will return the string "Extra". An
45 : * index of zero will return a zero length string.
46 : *
47 : * VALID RANGE
48 : *
49 : * These routines only convert dates in years 1 through 14 (Gregorian
50 : * dates 22 September 1792 through 22 September 1806). This more than
51 : * covers the period when the calendar was in use.
52 : *
53 : * I would support a wider range of dates, but I have not been able to
54 : * find an authoritative definition of when leap years were to have
55 : * occurred. There are suggestions that it was to skip a leap year ever
56 : * 100 years like the Gregorian calendar.
57 : *
58 : * CALENDAR OVERVIEW
59 : *
60 : * The French republican calendar was adopted in October 1793 during
61 : * the French Revolution and was abandoned in January 1806. The intent
62 : * was to create a new calendar system that was based on scientific
63 : * principals, not religious traditions.
64 : *
65 : * The year is divided into 12 months of 30 days each. The remaining 5
66 : * to 6 days in the year are grouped at the end and are holidays. Each
67 : * month is divided into three decades (instead of weeks) of 10 days
68 : * each.
69 : *
70 : * The epoch (first day of the first year) is 22 September 1792 in the
71 : * Gregorian calendar. Leap years are every fourth year (year 3, 7,
72 : * 11, etc.)
73 : *
74 : * TESTING
75 : *
76 : * This algorithm has been tested from the year 1 to 14. The source
77 : * code of the verification program is included in this package.
78 : *
79 : * REFERENCES
80 : *
81 : * I have found no detailed, authoritative reference on this calendar.
82 : * The algorithms are based on a preponderance of less authoritative
83 : * sources.
84 : *
85 : **************************************************************************/
86 :
87 : #include "sdncal.h"
88 :
89 : #define FRENCH_SDN_OFFSET 2375474
90 : #define DAYS_PER_4_YEARS 1461
91 : #define DAYS_PER_MONTH 30
92 : #define FIRST_VALID 2375840
93 : #define LAST_VALID 2380952
94 :
95 : void SdnToFrench(
96 : long int sdn,
97 : int *pYear,
98 : int *pMonth,
99 : int *pDay)
100 50 : {
101 : long int temp;
102 : int dayOfYear;
103 :
104 50 : if (sdn < FIRST_VALID || sdn > LAST_VALID) {
105 46 : *pYear = 0;
106 46 : *pMonth = 0;
107 46 : *pDay = 0;
108 46 : return;
109 : }
110 4 : temp = (sdn - FRENCH_SDN_OFFSET) * 4 - 1;
111 4 : *pYear = temp / DAYS_PER_4_YEARS;
112 4 : dayOfYear = (temp % DAYS_PER_4_YEARS) / 4;
113 4 : *pMonth = dayOfYear / DAYS_PER_MONTH + 1;
114 4 : *pDay = dayOfYear % DAYS_PER_MONTH + 1;
115 : }
116 :
117 : long int FrenchToSdn(
118 : int year,
119 : int month,
120 : int day)
121 5 : {
122 : /* check for invalid dates */
123 5 : if (year < 1 || year > 14 ||
124 : month < 1 || month > 13 ||
125 : day < 1 || day > 30) {
126 4 : return (0);
127 : }
128 1 : return ((year * DAYS_PER_4_YEARS) / 4
129 : + (month - 1) * DAYS_PER_MONTH
130 : + day
131 : + FRENCH_SDN_OFFSET);
132 : }
133 :
134 : char *FrenchMonthName[14] =
135 : {
136 : "",
137 : "Vendemiaire",
138 : "Brumaire",
139 : "Frimaire",
140 : "Nivose",
141 : "Pluviose",
142 : "Ventose",
143 : "Germinal",
144 : "Floreal",
145 : "Prairial",
146 : "Messidor",
147 : "Thermidor",
148 : "Fructidor",
149 : "Extra"
150 : };
151 :
152 :
153 : /*
154 : * Local variables:
155 : * tab-width: 4
156 : * c-basic-offset: 4
157 : * End:
158 : * vim600: sw=4 ts=4 fdm=marker
159 : * vim<600: sw=4 ts=4
160 : */
|