root/ext/calendar/french.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. SdnToFrench
  2. FrenchToSdn

   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                                         zend_long sdn,
  97                                         int *pYear,
  98                                         int *pMonth,
  99                                         int *pDay)
 100 {
 101         zend_long temp;
 102         int dayOfYear;
 103 
 104         if (sdn < FIRST_VALID || sdn > LAST_VALID) {
 105                 *pYear = 0;
 106                 *pMonth = 0;
 107                 *pDay = 0;
 108                 return;
 109         }
 110         temp = (sdn - FRENCH_SDN_OFFSET) * 4 - 1;
 111         *pYear = temp / DAYS_PER_4_YEARS;
 112         dayOfYear = (temp % DAYS_PER_4_YEARS) / 4;
 113         *pMonth = dayOfYear / DAYS_PER_MONTH + 1;
 114         *pDay = dayOfYear % DAYS_PER_MONTH + 1;
 115 }
 116 
 117 zend_long FrenchToSdn(
 118                                                 int year,
 119                                                 int month,
 120                                                 int day)
 121 {
 122         /* check for invalid dates */
 123         if (year < 1 || year > 14 ||
 124                 month < 1 || month > 13 ||
 125                 day < 1 || day > 30) {
 126                 return (0);
 127         }
 128         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  */

/* [<][>][^][v][top][bottom][index][help] */