Example #1
0
        internal override LocalInstant AddMonths(LocalInstant localInstant, int months)
        {
            // Note: this method gives the same result regardless of the month numbering used
            // by the instance. The method works in terms of civil month numbers for most of
            // the time in order to simplify the logic.
            if (months == 0)
            {
                return(localInstant);
            }
            long tickOfDay = TimeOfDayCalculator.GetTickOfDay(localInstant);
            var  startDate = HebrewScripturalCalculator.HebrewFromAbsolute(AbsoluteDayFromLocalInstant(localInstant));
            int  year      = startDate.Year;
            int  month     = HebrewMonthConverter.ScripturalToCivil(year, startDate.Month);

            // This arithmetic works the same both backwards and forwards.
            year  += (months / MonthsPerLeapCycle) * YearsPerLeapCycle;
            months = months % MonthsPerLeapCycle;
            if (months > 0)
            {
                // Add as many months as we need to in order to act as if we'd begun at the start
                // of the year, for simplicity.
                months += month - 1;
                // Add a year at a time
                while (months >= GetMaxMonth(year))
                {
                    months -= GetMaxMonth(year);
                    year++;
                }
                // However many months we've got left to add tells us the final month.
                month = months + 1;
            }
            else
            {
                // Pretend we were given the month at the end of the years.
                months -= GetMaxMonth(year) - month;
                // Subtract a year at a time
                while (months + GetMaxMonth(year) <= 0)
                {
                    months += GetMaxMonth(year);
                    year--;
                }
                // However many months we've got left to add (which will still be negative...)
                // tells us the final month.
                month = GetMaxMonth(year) + months;
            }

            // Convert back to scriptural for the last bit
            month = HebrewMonthConverter.CivilToScriptural(year, month);
            int day         = Math.Min(HebrewScripturalCalculator.DaysInMonth(year, month), startDate.Day);
            int absoluteDay = HebrewScripturalCalculator.AbsoluteFromHebrew(year, month, day);

            return(LocalInstantFromAbsoluteDay(absoluteDay, tickOfDay));
        }
        internal override YearMonthDay GetYearMonthDay(int year, int dayOfYear)
        {
            YearMonthDay scriptural = HebrewScripturalCalculator.GetYearMonthDay(year, dayOfYear);

            return(monthNumbering == HebrewMonthNumbering.Scriptural ? scriptural : new YearMonthDay(year, HebrewMonthConverter.ScripturalToCivil(year, scriptural.Month), scriptural.Day));
        }
 private int ScripturalToCalendarMonth(int year, int month) =>
 monthNumbering == HebrewMonthNumbering.Scriptural ? month : HebrewMonthConverter.ScripturalToCivil(year, month);
Example #4
0
        // Note to self: this is (minuendInstant - subtrahendInstant) in months. So if minuendInstant
        // is later than subtrahendInstant, the result should be positive.
        internal override int MonthsBetween(LocalInstant minuendInstant, LocalInstant subtrahendInstant)
        {
            var minuendDate    = HebrewScripturalCalculator.HebrewFromAbsolute(AbsoluteDayFromLocalInstant(minuendInstant));
            var subtrahendDate = HebrewScripturalCalculator.HebrewFromAbsolute(AbsoluteDayFromLocalInstant(subtrahendInstant));
            // First (quite rough) guess... we could probably be more efficient than this, but it's unlikely to be very far off.
            double minuendMonths    = (minuendDate.Year * MonthsPerLeapCycle) / (double)YearsPerLeapCycle + HebrewMonthConverter.ScripturalToCivil(minuendDate.Year, minuendDate.Month);
            double subtrahendMonths = (subtrahendDate.Year * MonthsPerLeapCycle) / (double)YearsPerLeapCycle + HebrewMonthConverter.ScripturalToCivil(subtrahendDate.Year, subtrahendDate.Month);
            int    diff             = (int)(minuendMonths - subtrahendMonths);

            if (subtrahendInstant <= minuendInstant)
            {
                // Go backwards until we've got a tight upper bound...
                while (AddMonths(subtrahendInstant, diff) > minuendInstant)
                {
                    diff--;
                }
                // Go forwards until we've overshot
                while (AddMonths(subtrahendInstant, diff) <= minuendInstant)
                {
                    diff++;
                }
                // Take account of the overshoot
                return(diff - 1);
            }
            else
            {
                // Moving backwards, so we need to end up with a result greater than or equal to
                // minuendInstant...
                // Go forwards until we've got a tight upper bound...
                while (AddMonths(subtrahendInstant, diff) < minuendInstant)
                {
                    diff++;
                }
                // Go backwards until we've overshot
                while (AddMonths(subtrahendInstant, diff) >= minuendInstant)
                {
                    diff--;
                }
                // Take account of the overshoot
                return(diff + 1);
            }
        }