PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - calendar - jewish.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 184
Code covered: 73.9 % Executed lines: 136
Legend: not executed executed

       1                 : /* $selId: jewish.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                 :  *     SdnToJewish(
      14                 :  *         long int sdn,
      15                 :  *         int *pYear,
      16                 :  *         int *pMonth,
      17                 :  *         int *pDay);
      18                 :  *
      19                 :  * Convert a SDN to a Jewish calendar date.  If the input SDN is before the
      20                 :  * first day of year 1, the three output values will all be set to zero,
      21                 :  * otherwise *pYear will be > 0; *pMonth will be in the range 1 to 13
      22                 :  * inclusive; *pDay will be in the range 1 to 30 inclusive.  Note that Adar
      23                 :  * II is assigned the month number 7 and Elul is always 13.
      24                 :  *
      25                 :  *     long int
      26                 :  *     JewishToSdn(
      27                 :  *         int year,
      28                 :  *         int month,
      29                 :  *         int day);
      30                 :  *
      31                 :  * Convert a Jewish calendar date to a SDN.  Zero is returned when the
      32                 :  * input date is detected as invalid or out of the supported range.  The
      33                 :  * return value will be > 0 for all valid, supported dates, but there are
      34                 :  * some invalid dates that will return a positive value.  To verify that a
      35                 :  * date is valid, convert it to SDN and then back and compare with the
      36                 :  * original.
      37                 :  *
      38                 :  *     char *JewishMonthName[14];
      39                 :  *
      40                 :  * Convert a Jewish month number (1 to 13) to the name of the Jewish month
      41                 :  * (null terminated).  An index of zero will return a zero length string.
      42                 :  *
      43                 :  * VALID RANGE
      44                 :  *
      45                 :  *     Although this software can handle dates all the way back to the year
      46                 :  *     1 (3761 B.C.), such use may not be meaningful.
      47                 :  *
      48                 :  *     The Jewish calendar has been in use for several thousand years, but
      49                 :  *     in the early days there was no formula to determine the start of a
      50                 :  *     month.  A new month was started when the new moon was first
      51                 :  *     observed.
      52                 :  *
      53                 :  *     It is not clear when the current rule based calendar replaced the
      54                 :  *     observation based calendar.  According to the book "Jewish Calendar
      55                 :  *     Mystery Dispelled" by George Zinberg, the patriarch Hillel II
      56                 :  *     published these rules in 358 A.D.  But, according to The
      57                 :  *     Encyclopedia Judaica, Hillel II may have only published the 19 year
      58                 :  *     rule for determining the occurrence of leap years.
      59                 :  *
      60                 :  *     I have yet to find a specific date when the current set of rules
      61                 :  *     were known to be in use.
      62                 :  *
      63                 :  * CALENDAR OVERVIEW
      64                 :  *
      65                 :  *     The Jewish calendar is based on lunar as well as solar cycles.  A
      66                 :  *     month always starts on or near a new moon and has either 29 or 30
      67                 :  *     days (a lunar cycle is about 29 1/2 days).  Twelve of these
      68                 :  *     alternating 29-30 day months gives a year of 354 days, which is
      69                 :  *     about 11 1/4 days short of a solar year.
      70                 :  *
      71                 :  *     Since a month is defined to be a lunar cycle (new moon to new moon),
      72                 :  *     this 11 1/4 day difference cannot be overcome by adding days to a
      73                 :  *     month as with the Gregorian calendar, so an entire month is
      74                 :  *     periodically added to the year, making some years 13 months long.
      75                 :  *
      76                 :  *     For astronomical as well as ceremonial reasons, the start of a new
      77                 :  *     year may be delayed until a day or two after the new moon causing
      78                 :  *     years to vary in length.  Leap years can be from 383 to 385 days and
      79                 :  *     common years can be from 353 to 355 days.  These are the months of
      80                 :  *     the year and their possible lengths:
      81                 :  *
      82                 :  *                       COMMON YEAR          LEAP YEAR
      83                 :  *          1 Tishri    30   30   30         30   30   30
      84                 :  *          2 Heshvan   29   29   30         29   29   30 (variable)
      85                 :  *          3 Kislev    29   30   30         29   30   30 (variable)
      86                 :  *          4 Tevet     29   29   29         29   29   29
      87                 :  *          5 Shevat    30   30   30         30   30   30
      88                 :  *          6 Adar I    29   29   29         30   30   30 (variable)
      89                 :  *          7 Adar II   --   --   --         29   29   29 (optional)
      90                 :  *          8 Nisan     30   30   30         30   30   30
      91                 :  *          9 Iyyar     29   29   29         29   29   29
      92                 :  *         10 Sivan     30   30   30         30   30   30
      93                 :  *         11 Tammuz    29   29   29         29   29   29
      94                 :  *         12 Av        30   30   30         30   30   30
      95                 :  *         13 Elul      29   29   29         29   29   29
      96                 :  *                     ---  ---  ---        ---  ---  ---
      97                 :  *                     353  354  355        383  384  385
      98                 :  *
      99                 :  *     Note that the month names and other words that appear in this file
     100                 :  *     have multiple possible spellings in the Roman character set.  I have
     101                 :  *     chosen to use the spellings found in the Encyclopedia Judaica.
     102                 :  *
     103                 :  *     Adar II, the month added for leap years, is sometimes referred to as
     104                 :  *     the 13th month, but I have chosen to assign it the number 7 to keep
     105                 :  *     the months in chronological order.  This may not be consistent with
     106                 :  *     other numbering schemes.
     107                 :  *
     108                 :  *     Leap years occur in a fixed pattern of 19 years called the metonic
     109                 :  *     cycle.  The 3rd, 6th, 8th, 11th, 14th, 17th and 19th years of this
     110                 :  *     cycle are leap years.  The first metonic cycle starts with Jewish
     111                 :  *     year 1, or 3761/60 B.C.  This is believed to be the year of
     112                 :  *     creation.
     113                 :  *
     114                 :  *     To construct the calendar for a year, you must first find the length
     115                 :  *     of the year by determining the first day of the year (Tishri 1, or
     116                 :  *     Rosh Ha-Shanah) and the first day of the following year.  This
     117                 :  *     selects one of the six possible month length configurations listed
     118                 :  *     above.
     119                 :  *
     120                 :  *     Finding the first day of the year is the most difficult part.
     121                 :  *     Finding the date and time of the new moon (or molad) is the first
     122                 :  *     step.  For this purpose, the lunar cycle is assumed to be 29 days 12
     123                 :  *     hours and 793 halakim.  A halakim is 1/1080th of an hour or 3 1/3
     124                 :  *     seconds.  (This assumed value is only about 1/2 second less than the
     125                 :  *     value used by modern astronomers -- not bad for a number that was
     126                 :  *     determined so long ago.)  The first molad of year 1 occurred on
     127                 :  *     Sunday at 11:20:11 P.M.  This would actually be Monday, because the
     128                 :  *     Jewish day is considered to begin at sunset.
     129                 :  *
     130                 :  *     Since sunset varies, the day is assumed to begin at 6:00 P.M.  for
     131                 :  *     calendar calculation purposes.  So, the first molad was 5 hours 793
     132                 :  *     halakim after the start of Tishri 1, 0001 (which was Monday
     133                 :  *     September 7, 4761 B.C. by the Gregorian calendar).  All subsequent
     134                 :  *     molads can be calculated from this starting point by adding the
     135                 :  *     length of a lunar cycle.
     136                 :  *
     137                 :  *     Once the molad that starts a year is determined the actual start of
     138                 :  *     the year (Tishri 1) can be determined.  Tishri 1 will be the day of
     139                 :  *     the molad unless it is delayed by one of the following four rules
     140                 :  *     (called dehiyyot).  Each rule can delay the start of the year by one
     141                 :  *     day, and since rule #1 can combine with one of the other rules, it
     142                 :  *     can be delayed as much as two days.
     143                 :  *
     144                 :  *         1.  Tishri 1 must never be Sunday, Wednesday or Friday.  (This
     145                 :  *             is largely to prevent certain holidays from occurring on the
     146                 :  *             day before or after the Sabbath.)
     147                 :  *
     148                 :  *         2.  If the molad occurs on or after noon, Tishri 1 must be
     149                 :  *             delayed.
     150                 :  *
     151                 :  *         3.  If it is a common (not leap) year and the molad occurs on
     152                 :  *             Tuesday at or after 3:11:20 A.M., Tishri 1 must be delayed.
     153                 :  *
     154                 :  *         4.  If it is the year following a leap year and the molad occurs
     155                 :  *             on Monday at or after 9:32:43 and 1/3 sec, Tishri 1 must be
     156                 :  *             delayed.
     157                 :  *
     158                 :  * GLOSSARY
     159                 :  *
     160                 :  *     dehiyyot         The set of 4 rules that determine when the new year
     161                 :  *                      starts relative to the molad.
     162                 :  *
     163                 :  *     halakim          1/1080th of an hour or 3 1/3 seconds.
     164                 :  *
     165                 :  *     lunar cycle      The period of time between mean conjunctions of the
     166                 :  *                      sun and moon (new moon to new moon).  This is
     167                 :  *                      assumed to be 29 days 12 hours and 793 halakim for
     168                 :  *                      calendar purposes.
     169                 :  *
     170                 :  *     metonic cycle    A 19 year cycle which determines which years are
     171                 :  *                      leap years and which are common years.  The 3rd,
     172                 :  *                      6th, 8th, 11th, 14th, 17th and 19th years of this
     173                 :  *                      cycle are leap years.
     174                 :  *
     175                 :  *     molad            The date and time of the mean conjunction of the
     176                 :  *                      sun and moon (new moon).  This is the approximate
     177                 :  *                      beginning of a month.
     178                 :  *
     179                 :  *     Rosh Ha-Shanah   The first day of the Jewish year (Tishri 1).
     180                 :  *
     181                 :  *     Tishri           The first month of the Jewish year.
     182                 :  *
     183                 :  * ALGORITHMS
     184                 :  *
     185                 :  *     SERIAL DAY NUMBER TO JEWISH DATE
     186                 :  *
     187                 :  *     The simplest approach would be to use the rules stated above to find
     188                 :  *     the molad of Tishri before and after the given day number.  Then use
     189                 :  *     the molads to find Tishri 1 of the current and following years.
     190                 :  *     From this the length of the year can be determined and thus the
     191                 :  *     length of each month.  But this method is used as a last resort.
     192                 :  *
     193                 :  *     The first 59 days of the year are the same regardless of the length
     194                 :  *     of the year.  As a result, only the day number of the start of the
     195                 :  *     year is required.
     196                 :  *
     197                 :  *     Similarly, the last 6 months do not change from year to year.  And
     198                 :  *     since it can be determined whether the year is a leap year by simple
     199                 :  *     division, the lengths of Adar I and II can be easily calculated.  In
     200                 :  *     fact, all dates after the 3rd month are consistent from year to year
     201                 :  *     (once it is known whether it is a leap year).
     202                 :  *
     203                 :  *     This means that if the given day number falls in the 3rd month or on
     204                 :  *     the 30th day of the 2nd month the length of the year must be found,
     205                 :  *     but in no other case.
     206                 :  *
     207                 :  *     So, the approach used is to take the given day number and round it
     208                 :  *     to the closest molad of Tishri (first new moon of the year).  The
     209                 :  *     rounding is not really to the *closest* molad, but is such that if
     210                 :  *     the day number is before the middle of the 3rd month the molad at
     211                 :  *     the start of the year is found, otherwise the molad at the end of
     212                 :  *     the year is found.
     213                 :  *
     214                 :  *     Only if the day number is actually found to be in the ambiguous
     215                 :  *     period of 29 to 31 days is the other molad calculated.
     216                 :  *
     217                 :  *     JEWISH DATE TO SERIAL DAY NUMBER
     218                 :  *
     219                 :  *     The year number is used to find which 19 year metonic cycle contains
     220                 :  *     the date and which year within the cycle (this is a division and
     221                 :  *     modulus).  This also determines whether it is a leap year.
     222                 :  *
     223                 :  *     If the month is 1 or 2, the calculation is simple addition to the
     224                 :  *     first of the year.
     225                 :  *
     226                 :  *     If the month is 8 (Nisan) or greater, the calculation is simple
     227                 :  *     subtraction from beginning of the following year.
     228                 :  *
     229                 :  *     If the month is 4 to 7, it is considered whether it is a leap year
     230                 :  *     and then simple subtraction from the beginning of the following year
     231                 :  *     is used.
     232                 :  *
     233                 :  *     Only if it is the 3rd month is both the start and end of the year
     234                 :  *     required.
     235                 :  *
     236                 :  * TESTING
     237                 :  *
     238                 :  *     This algorithm has been tested in two ways.  First, 510 dates from a
     239                 :  *     table in "Jewish Calendar Mystery Dispelled" were calculated and
     240                 :  *     compared to the table.  Second, the calculation algorithm described
     241                 :  *     in "Jewish Calendar Mystery Dispelled" was coded and used to verify
     242                 :  *     all dates from the year 1 (3761 B.C.) to the year 13760 (10000
     243                 :  *     A.D.).
     244                 :  *
     245                 :  *     The source code of the verification program is included in this
     246                 :  *     package.
     247                 :  *
     248                 :  * REFERENCES
     249                 :  *
     250                 :  *     The Encyclopedia Judaica, the entry for "Calendar"
     251                 :  *
     252                 :  *     The Jewish Encyclopedia
     253                 :  *
     254                 :  *     Jewish Calendar Mystery Dispelled by George Zinberg, Vantage Press,
     255                 :  *     1963
     256                 :  *
     257                 :  *     The Comprehensive Hebrew Calendar by Arthur Spier, Behrman House
     258                 :  *
     259                 :  *     The Book of Calendars [note that this work contains many typos]
     260                 :  *
     261                 :  **************************************************************************/
     262                 : 
     263                 : #if defined(PHP_WIN32) && _MSC_VER >= 1200
     264                 : #pragma setlocale("english")
     265                 : #endif
     266                 : 
     267                 : #include "sdncal.h"
     268                 : 
     269                 : #define HALAKIM_PER_HOUR 1080
     270                 : #define HALAKIM_PER_DAY 25920
     271                 : #define HALAKIM_PER_LUNAR_CYCLE ((29 * HALAKIM_PER_DAY) + 13753)
     272                 : #define HALAKIM_PER_METONIC_CYCLE (HALAKIM_PER_LUNAR_CYCLE * (12 * 19 + 7))
     273                 : 
     274                 : #define JEWISH_SDN_OFFSET 347997
     275                 : #define NEW_MOON_OF_CREATION 31524
     276                 : 
     277                 : #define SUNDAY    0
     278                 : #define MONDAY    1
     279                 : #define TUESDAY   2
     280                 : #define WEDNESDAY 3
     281                 : #define THURSDAY  4
     282                 : #define FRIDAY    5
     283                 : #define SATURDAY  6
     284                 : 
     285                 : #define NOON (18 * HALAKIM_PER_HOUR)
     286                 : #define AM3_11_20 ((9 * HALAKIM_PER_HOUR) + 204)
     287                 : #define AM9_32_43 ((15 * HALAKIM_PER_HOUR) + 589)
     288                 : 
     289                 : static int monthsPerYear[19] =
     290                 : {
     291                 : 12, 12, 13, 12, 12, 13, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 13
     292                 : };
     293                 : 
     294                 : static int yearOffset[19] =
     295                 : {
     296                 :         0, 12, 24, 37, 49, 61, 74, 86, 99, 111, 123,
     297                 :         136, 148, 160, 173, 185, 197, 210, 222
     298                 : };
     299                 : 
     300                 : char *JewishMonthName[14] =
     301                 : {
     302                 :         "",
     303                 :         "Tishri",
     304                 :         "Heshvan",
     305                 :         "Kislev",
     306                 :         "Tevet",
     307                 :         "Shevat",
     308                 :         "AdarI",
     309                 :         "AdarII",
     310                 :         "Nisan",
     311                 :         "Iyyar",
     312                 :         "Sivan",
     313                 :         "Tammuz",
     314                 :         "Av",
     315                 :         "Elul"
     316                 : };
     317                 : 
     318                 : char *JewishMonthHebName[14] =
     319                 : {
     320                 :         "",
     321                 :         "תשרי",
     322                 :         "חשון",
     323                 :         "כסלו",
     324                 :         "טבת",
     325                 :         "שבט",
     326                 :         "אדר",
     327                 :         "'אדר ב",
     328                 :         "ניסן",
     329                 :         "אייר",
     330                 :         "סיון",
     331                 :         "תמוז",
     332                 :         "אב",
     333                 :         "אלול"
     334                 : };
     335                 : 
     336                 : /************************************************************************
     337                 :  * Given the year within the 19 year metonic cycle and the time of a molad
     338                 :  * (new moon) which starts that year, this routine will calculate what day
     339                 :  * will be the actual start of the year (Tishri 1 or Rosh Ha-Shanah).  This
     340                 :  * first day of the year will be the day of the molad unless one of 4 rules
     341                 :  * (called dehiyyot) delays it.  These 4 rules can delay the start of the
     342                 :  * year by as much as 2 days.
     343                 :  */
     344                 : static long int Tishri1(
     345                 :                                                    int metonicYear,
     346                 :                                                    long int moladDay,
     347                 :                                                    long int moladHalakim)
     348              59 : {
     349                 :         long int tishri1;
     350                 :         int dow;
     351                 :         int leapYear;
     352                 :         int lastWasLeapYear;
     353                 : 
     354              59 :         tishri1 = moladDay;
     355              59 :         dow = tishri1 % 7;
     356              59 :         leapYear = metonicYear == 2 || metonicYear == 5 || metonicYear == 7
     357                 :                 || metonicYear == 10 || metonicYear == 13 || metonicYear == 16
     358                 :                 || metonicYear == 18;
     359              59 :         lastWasLeapYear = metonicYear == 3 || metonicYear == 6
     360                 :                 || metonicYear == 8 || metonicYear == 11 || metonicYear == 14
     361                 :                 || metonicYear == 17 || metonicYear == 0;
     362                 : 
     363                 :         /* Apply rules 2, 3 and 4. */
     364              59 :         if ((moladHalakim >= NOON) ||
     365                 :                 ((!leapYear) && dow == TUESDAY && moladHalakim >= AM3_11_20) ||
     366                 :                 (lastWasLeapYear && dow == MONDAY && moladHalakim >= AM9_32_43)) {
     367              17 :                 tishri1++;
     368              17 :                 dow++;
     369              17 :                 if (dow == 7) {
     370               0 :                         dow = 0;
     371                 :                 }
     372                 :         }
     373                 :         /* Apply rule 1 after the others because it can cause an additional
     374                 :          * delay of one day. */
     375              59 :         if (dow == WEDNESDAY || dow == FRIDAY || dow == SUNDAY) {
     376               8 :                 tishri1++;
     377                 :         }
     378              59 :         return (tishri1);
     379                 : }
     380                 : 
     381                 : /************************************************************************
     382                 :  * Given a metonic cycle number, calculate the date and time of the molad
     383                 :  * (new moon) that starts that cycle.  Since the length of a metonic cycle
     384                 :  * is a constant, this is a simple calculation, except that it requires an
     385                 :  * intermediate value which is bigger that 32 bits.  Because this
     386                 :  * intermediate value only needs 36 to 37 bits and the other numbers are
     387                 :  * constants, the process has been reduced to just a few steps.
     388                 :  */
     389                 : static void MoladOfMetonicCycle(
     390                 :                                                                    int metonicCycle,
     391                 :                                                                    long int *pMoladDay,
     392                 :                                                                    long int *pMoladHalakim)
     393              59 : {
     394                 :         register unsigned long int r1, r2, d1, d2;
     395                 : 
     396                 :         /* Start with the time of the first molad after creation. */
     397              59 :         r1 = NEW_MOON_OF_CREATION;
     398                 : 
     399                 :         /* Calculate metonicCycle * HALAKIM_PER_METONIC_CYCLE.  The upper 32
     400                 :          * bits of the result will be in r2 and the lower 16 bits will be
     401                 :          * in r1. */
     402              59 :         r1 += metonicCycle * (HALAKIM_PER_METONIC_CYCLE & 0xFFFF);
     403              59 :         r2 = r1 >> 16;
     404              59 :         r2 += metonicCycle * ((HALAKIM_PER_METONIC_CYCLE >> 16) & 0xFFFF);
     405                 : 
     406                 :         /* Calculate r2r1 / HALAKIM_PER_DAY.  The remainder will be in r1, the
     407                 :          * upper 16 bits of the quotient will be in d2 and the lower 16 bits
     408                 :          * will be in d1. */
     409              59 :         d2 = r2 / HALAKIM_PER_DAY;
     410              59 :         r2 -= d2 * HALAKIM_PER_DAY;
     411              59 :         r1 = (r2 << 16) | (r1 & 0xFFFF);
     412              59 :         d1 = r1 / HALAKIM_PER_DAY;
     413              59 :         r1 -= d1 * HALAKIM_PER_DAY;
     414                 : 
     415              59 :         *pMoladDay = (d2 << 16) | d1;
     416              59 :         *pMoladHalakim = r1;
     417              59 : }
     418                 : 
     419                 : /************************************************************************
     420                 :  * Given a day number, find the molad of Tishri (the new moon at the start
     421                 :  * of a year) which is closest to that day number.  It's not really the
     422                 :  * *closest* molad that we want here.  If the input day is in the first two
     423                 :  * months, we want the molad at the start of the year.  If the input day is
     424                 :  * in the fourth to last months, we want the molad at the end of the year.
     425                 :  * If the input day is in the third month, it doesn't matter which molad is
     426                 :  * returned, because both will be required.  This type of "rounding" allows
     427                 :  * us to avoid calculating the length of the year in most cases.
     428                 :  */
     429                 : static void FindTishriMolad(
     430                 :                                                            long int inputDay,
     431                 :                                                            int *pMetonicCycle,
     432                 :                                                            int *pMetonicYear,
     433                 :                                                            long int *pMoladDay,
     434                 :                                                            long int *pMoladHalakim)
     435              56 : {
     436                 :         long int moladDay;
     437                 :         long int moladHalakim;
     438                 :         int metonicCycle;
     439                 :         int metonicYear;
     440                 : 
     441                 :         /* Estimate the metonic cycle number.  Note that this may be an under
     442                 :          * estimate because there are 6939.6896 days in a metonic cycle not
     443                 :          * 6940, but it will never be an over estimate.  The loop below will
     444                 :          * correct for any error in this estimate. */
     445              56 :         metonicCycle = (inputDay + 310) / 6940;
     446                 : 
     447                 :         /* Calculate the time of the starting molad for this metonic cycle. */
     448              56 :         MoladOfMetonicCycle(metonicCycle, &moladDay, &moladHalakim);
     449                 : 
     450                 :         /* If the above was an under estimate, increment the cycle number until
     451                 :          * the correct one is found.  For modern dates this loop is about 98.6%
     452                 :          * likely to not execute, even once, because the above estimate is
     453                 :          * really quite close. */
     454             112 :         while (moladDay < inputDay - 6940 + 310) {
     455               0 :                 metonicCycle++;
     456               0 :                 moladHalakim += HALAKIM_PER_METONIC_CYCLE;
     457               0 :                 moladDay += moladHalakim / HALAKIM_PER_DAY;
     458               0 :                 moladHalakim = moladHalakim % HALAKIM_PER_DAY;
     459                 :         }
     460                 : 
     461                 :         /* Find the molad of Tishri closest to this date. */
     462             513 :         for (metonicYear = 0; metonicYear < 18; metonicYear++) {
     463             513 :                 if (moladDay > inputDay - 74) {
     464              56 :                         break;
     465                 :                 }
     466             457 :                 moladHalakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear];
     467             457 :                 moladDay += moladHalakim / HALAKIM_PER_DAY;
     468             457 :                 moladHalakim = moladHalakim % HALAKIM_PER_DAY;
     469                 :         }
     470                 : 
     471              56 :         *pMetonicCycle = metonicCycle;
     472              56 :         *pMetonicYear = metonicYear;
     473              56 :         *pMoladDay = moladDay;
     474              56 :         *pMoladHalakim = moladHalakim;
     475              56 : }
     476                 : 
     477                 : /************************************************************************
     478                 :  * Given a year, find the number of the first day of that year and the date
     479                 :  * and time of the starting molad.
     480                 :  */
     481                 : static void FindStartOfYear(
     482                 :                                                            int year,
     483                 :                                                            int *pMetonicCycle,
     484                 :                                                            int *pMetonicYear,
     485                 :                                                            long int *pMoladDay,
     486                 :                                                            long int *pMoladHalakim,
     487                 :                                                            int *pTishri1)
     488               3 : {
     489               3 :         *pMetonicCycle = (year - 1) / 19;
     490               3 :         *pMetonicYear = (year - 1) % 19;
     491               3 :         MoladOfMetonicCycle(*pMetonicCycle, pMoladDay, pMoladHalakim);
     492                 : 
     493               3 :         *pMoladHalakim += HALAKIM_PER_LUNAR_CYCLE * yearOffset[*pMetonicYear];
     494               3 :         *pMoladDay += *pMoladHalakim / HALAKIM_PER_DAY;
     495               3 :         *pMoladHalakim = *pMoladHalakim % HALAKIM_PER_DAY;
     496                 : 
     497               3 :         *pTishri1 = Tishri1(*pMetonicYear, *pMoladDay, *pMoladHalakim);
     498               3 : }
     499                 : 
     500                 : /************************************************************************
     501                 :  * Given a serial day number (SDN), find the corresponding year, month and
     502                 :  * day in the Jewish calendar.  The three output values will always be
     503                 :  * modified.  If the input SDN is before the first day of year 1, they will
     504                 :  * all be set to zero, otherwise *pYear will be > 0; *pMonth will be in the
     505                 :  * range 1 to 13 inclusive; *pDay will be in the range 1 to 30 inclusive.
     506                 :  */
     507                 : void SdnToJewish(
     508                 :                                         long int sdn,
     509                 :                                         int *pYear,
     510                 :                                         int *pMonth,
     511                 :                                         int *pDay)
     512              54 : {
     513                 :         long int inputDay;
     514                 :         long int day;
     515                 :         long int halakim;
     516                 :         int metonicCycle;
     517                 :         int metonicYear;
     518                 :         int tishri1;
     519                 :         int tishri1After;
     520                 :         int yearLength;
     521                 : 
     522              54 :         if (sdn <= JEWISH_SDN_OFFSET) {
     523               1 :                 *pYear = 0;
     524               1 :                 *pMonth = 0;
     525               1 :                 *pDay = 0;
     526               1 :                 return;
     527                 :         }
     528              53 :         inputDay = sdn - JEWISH_SDN_OFFSET;
     529                 : 
     530              53 :         FindTishriMolad(inputDay, &metonicCycle, &metonicYear, &day, &halakim);
     531              53 :         tishri1 = Tishri1(metonicYear, day, halakim);
     532                 : 
     533              53 :         if (inputDay >= tishri1) {
     534                 :                 /* It found Tishri 1 at the start of the year. */
     535              17 :                 *pYear = metonicCycle * 19 + metonicYear + 1;
     536              17 :                 if (inputDay < tishri1 + 59) {
     537              17 :                         if (inputDay < tishri1 + 30) {
     538               4 :                                 *pMonth = 1;
     539               4 :                                 *pDay = inputDay - tishri1 + 1;
     540                 :                         } else {
     541              13 :                                 *pMonth = 2;
     542              13 :                                 *pDay = inputDay - tishri1 - 29;
     543                 :                         }
     544              17 :                         return;
     545                 :                 }
     546                 :                 /* We need the length of the year to figure this out, so find
     547                 :                  * Tishri 1 of the next year. */
     548               0 :                 halakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear];
     549               0 :                 day += halakim / HALAKIM_PER_DAY;
     550               0 :                 halakim = halakim % HALAKIM_PER_DAY;
     551               0 :                 tishri1After = Tishri1((metonicYear + 1) % 19, day, halakim);
     552                 :         } else {
     553                 :                 /* It found Tishri 1 at the end of the year. */
     554              36 :                 *pYear = metonicCycle * 19 + metonicYear;
     555              36 :                 if (inputDay >= tishri1 - 177) {
     556                 :                         /* It is one of the last 6 months of the year. */
     557              21 :                         if (inputDay > tishri1 - 30) {
     558               4 :                                 *pMonth = 13;
     559               4 :                                 *pDay = inputDay - tishri1 + 30;
     560              17 :                         } else if (inputDay > tishri1 - 60) {
     561               3 :                                 *pMonth = 12;
     562               3 :                                 *pDay = inputDay - tishri1 + 60;
     563              14 :                         } else if (inputDay > tishri1 - 89) {
     564               4 :                                 *pMonth = 11;
     565               4 :                                 *pDay = inputDay - tishri1 + 89;
     566              10 :                         } else if (inputDay > tishri1 - 119) {
     567               3 :                                 *pMonth = 10;
     568               3 :                                 *pDay = inputDay - tishri1 + 119;
     569               7 :                         } else if (inputDay > tishri1 - 148) {
     570               3 :                                 *pMonth = 9;
     571               3 :                                 *pDay = inputDay - tishri1 + 148;
     572                 :                         } else {
     573               4 :                                 *pMonth = 8;
     574               4 :                                 *pDay = inputDay - tishri1 + 178;
     575                 :                         }
     576              21 :                         return;
     577                 :                 } else {
     578              15 :                         if (monthsPerYear[(*pYear - 1) % 19] == 13) {
     579               6 :                                 *pMonth = 7;
     580               6 :                                 *pDay = inputDay - tishri1 + 207;
     581               6 :                                 if (*pDay > 0)
     582               1 :                                         return;
     583               5 :                                 (*pMonth)--;
     584               5 :                                 (*pDay) += 30;
     585               5 :                                 if (*pDay > 0)
     586               1 :                                         return;
     587               4 :                                 (*pMonth)--;
     588               4 :                                 (*pDay) += 30;
     589                 :                         } else {
     590               9 :                                 *pMonth = 6;
     591               9 :                                 *pDay = inputDay - tishri1 + 207;
     592               9 :                                 if (*pDay > 0)
     593               2 :                                         return;
     594               7 :                                 (*pMonth)--;
     595               7 :                                 (*pDay) += 30;
     596                 :                         }
     597              11 :                         if (*pDay > 0)
     598               4 :                                 return;
     599               7 :                         (*pMonth)--;
     600               7 :                         (*pDay) += 29;
     601               7 :                         if (*pDay > 0)
     602               4 :                                 return;
     603                 : 
     604                 :                         /* We need the length of the year to figure this out, so find
     605                 :                          * Tishri 1 of this year. */
     606               3 :                         tishri1After = tishri1;
     607               3 :                         FindTishriMolad(day - 365,
     608                 :                                                         &metonicCycle, &metonicYear, &day, &halakim);
     609               3 :                         tishri1 = Tishri1(metonicYear, day, halakim);
     610                 :                 }
     611                 :         }
     612                 : 
     613               3 :         yearLength = tishri1After - tishri1;
     614               3 :         day = inputDay - tishri1 - 29;
     615               4 :         if (yearLength == 355 || yearLength == 385) {
     616                 :                 /* Heshvan has 30 days */
     617               1 :                 if (day <= 30) {
     618               0 :                         *pMonth = 2;
     619               0 :                         *pDay = day;
     620               0 :                         return;
     621                 :                 }
     622               1 :                 day -= 30;
     623                 :         } else {
     624                 :                 /* Heshvan has 29 days */
     625               2 :                 if (day <= 29) {
     626               0 :                         *pMonth = 2;
     627               0 :                         *pDay = day;
     628               0 :                         return;
     629                 :                 }
     630               2 :                 day -= 29;
     631                 :         }
     632                 : 
     633                 :         /* It has to be Kislev. */
     634               3 :         *pMonth = 3;
     635               3 :         *pDay = day;
     636                 : }
     637                 : 
     638                 : /************************************************************************
     639                 :  * Given a year, month and day in the Jewish calendar, find the
     640                 :  * corresponding serial day number (SDN).  Zero is returned when the input
     641                 :  * date is detected as invalid.  The return value will be > 0 for all valid
     642                 :  * dates, but there are some invalid dates that will return a positive
     643                 :  * value.  To verify that a date is valid, convert it to SDN and then back
     644                 :  * and compare with the original.
     645                 :  */
     646                 : long int JewishToSdn(
     647                 :                                                 int year,
     648                 :                                                 int month,
     649                 :                                                 int day)
     650               5 : {
     651                 :         long int sdn;
     652                 :         int metonicCycle;
     653                 :         int metonicYear;
     654                 :         int tishri1;
     655                 :         int tishri1After;
     656                 :         long int moladDay;
     657                 :         long int moladHalakim;
     658                 :         int yearLength;
     659                 :         int lengthOfAdarIAndII;
     660                 : 
     661               5 :         if (year <= 0 || day <= 0 || day > 30) {
     662               2 :                 return (0);
     663                 :         }
     664               3 :         switch (month) {
     665                 :                 case 1:
     666                 :                 case 2:
     667                 :                         /* It is Tishri or Heshvan - don't need the year length. */
     668               2 :                         FindStartOfYear(year, &metonicCycle, &metonicYear,
     669                 :                                                         &moladDay, &moladHalakim, &tishri1);
     670               2 :                         if (month == 1) {
     671               1 :                                 sdn = tishri1 + day - 1;
     672                 :                         } else {
     673               1 :                                 sdn = tishri1 + day + 29;
     674                 :                         }
     675               2 :                         break;
     676                 : 
     677                 :                 case 3:
     678                 :                         /* It is Kislev - must find the year length. */
     679                 : 
     680                 :                         /* Find the start of the year. */
     681               0 :                         FindStartOfYear(year, &metonicCycle, &metonicYear,
     682                 :                                                         &moladDay, &moladHalakim, &tishri1);
     683                 : 
     684                 :                         /* Find the end of the year. */
     685               0 :                         moladHalakim += HALAKIM_PER_LUNAR_CYCLE * monthsPerYear[metonicYear];
     686               0 :                         moladDay += moladHalakim / HALAKIM_PER_DAY;
     687               0 :                         moladHalakim = moladHalakim % HALAKIM_PER_DAY;
     688               0 :                         tishri1After = Tishri1((metonicYear + 1) % 19, moladDay, moladHalakim);
     689                 : 
     690               0 :                         yearLength = tishri1After - tishri1;
     691                 : 
     692               0 :                         if (yearLength == 355 || yearLength == 385) {
     693               0 :                                 sdn = tishri1 + day + 59;
     694                 :                         } else {
     695               0 :                                 sdn = tishri1 + day + 58;
     696                 :                         }
     697               0 :                         break;
     698                 : 
     699                 :                 case 4:
     700                 :                 case 5:
     701                 :                 case 6:
     702                 :                         /* It is Tevet, Shevat or Adar I - don't need the year length. */
     703                 : 
     704               0 :                         FindStartOfYear(year + 1, &metonicCycle, &metonicYear,
     705                 :                                                         &moladDay, &moladHalakim, &tishri1After);
     706                 : 
     707               0 :                         if (monthsPerYear[(year - 1) % 19] == 12) {
     708               0 :                                 lengthOfAdarIAndII = 29;
     709                 :                         } else {
     710               0 :                                 lengthOfAdarIAndII = 59;
     711                 :                         }
     712                 : 
     713               0 :                         if (month == 4) {
     714               0 :                                 sdn = tishri1After + day - lengthOfAdarIAndII - 237;
     715               0 :                         } else if (month == 5) {
     716               0 :                                 sdn = tishri1After + day - lengthOfAdarIAndII - 208;
     717                 :                         } else {
     718               0 :                                 sdn = tishri1After + day - lengthOfAdarIAndII - 178;
     719                 :                         }
     720               0 :                         break;
     721                 : 
     722                 :                 default:
     723                 :                         /* It is Adar II or later - don't need the year length. */
     724               1 :                         FindStartOfYear(year + 1, &metonicCycle, &metonicYear,
     725                 :                                                         &moladDay, &moladHalakim, &tishri1After);
     726                 : 
     727               1 :                         switch (month) {
     728                 :                                 case 7:
     729               0 :                                         sdn = tishri1After + day - 207;
     730               0 :                                         break;
     731                 :                                 case 8:
     732               1 :                                         sdn = tishri1After + day - 178;
     733               1 :                                         break;
     734                 :                                 case 9:
     735               0 :                                         sdn = tishri1After + day - 148;
     736               0 :                                         break;
     737                 :                                 case 10:
     738               0 :                                         sdn = tishri1After + day - 119;
     739               0 :                                         break;
     740                 :                                 case 11:
     741               0 :                                         sdn = tishri1After + day - 89;
     742               0 :                                         break;
     743                 :                                 case 12:
     744               0 :                                         sdn = tishri1After + day - 60;
     745               0 :                                         break;
     746                 :                                 case 13:
     747               0 :                                         sdn = tishri1After + day - 30;
     748               0 :                                         break;
     749                 :                                 default:
     750               0 :                                         return (0);
     751                 :                         }
     752                 :         }
     753               3 :         return (sdn + JEWISH_SDN_OFFSET);
     754                 : }
     755                 : 
     756                 : /*
     757                 :  * Local variables:
     758                 :  * tab-width: 4
     759                 :  * c-basic-offset: 4
     760                 :  * End:
     761                 :  * vim600: sw=4 ts=4 fdm=marker
     762                 :  * vim<600: sw=4 ts=4
     763                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:26:58 +0000 (3 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.