/// <summary>
 /// Change the year, maintaining month and day as well as possible. This doesn't
 /// work in the same way as other calendars; see http://judaism.stackexchange.com/questions/39053
 /// for the reasoning behind the rules.
 /// </summary>
 internal override YearMonthDay SetYear(YearMonthDay yearMonthDay, int year)
 {
     int currentYear = yearMonthDay.Year;
     int currentMonth = yearMonthDay.Month;
     int targetDay = yearMonthDay.Day;
     int targetScripturalMonth = CalendarToScripturalMonth(currentYear, currentMonth);
     if (targetScripturalMonth == 13 && !IsLeapYear(year))
     {
         // If we were in Adar II and the target year is not a leap year, map to Adar.
         targetScripturalMonth = 12;
     }
     else if (targetScripturalMonth == 12 && IsLeapYear(year) && !IsLeapYear(currentYear))
     {
         // If we were in Adar (non-leap year), go to Adar II rather than Adar I in a leap year.
         targetScripturalMonth = 13;
     }
     // If we're aiming for the 30th day of Heshvan, Kislev or an Adar, it's possible that the change in year
     // has meant the day becomes invalid. In that case, roll over to the 1st of the subsequent month.
     if (targetDay == 30 && (targetScripturalMonth == 8 || targetScripturalMonth == 9 || targetScripturalMonth == 12))
     {
         if (HebrewScripturalCalculator.DaysInMonth(year, targetScripturalMonth) != 30)
         {
             targetDay = 1;
             targetScripturalMonth++;
             // From Adar, roll to Nisan.
             if (targetScripturalMonth == 13)
             {
                 targetScripturalMonth = 1;
             }
         }
     }
     int targetCalendarMonth = ScripturalToCalendarMonth(year, targetScripturalMonth);
     return new YearMonthDay(year, targetCalendarMonth, targetDay);
 }
 /// <summary>
 /// Implements a simple year-setting policy, truncating the day
 /// if necessary.
 /// </summary>
 internal override YearMonthDay SetYear(YearMonthDay yearMonthDay, [Trusted] int year)
 {
     // TODO(2.0): All subclasses have the same logic of "detect leap years,
     // and otherwise we're fine". Put it here instead.
     int currentMonth = yearMonthDay.Month;
     int currentDay = yearMonthDay.Day;
     int newDay = GetDaysInMonth(year, currentMonth);
     return new YearMonthDay(year, currentMonth, Math.Min(currentDay, newDay));
 }
 internal override YearMonthDay SetYear(YearMonthDay yearMonthDay, [Trusted] int year)
 {
     int month = yearMonthDay.Month;
     int day = yearMonthDay.Day;
     // The only value which might change day is Feb 29th.
     if (month == 2 && day == 29 && !IsLeapYear(year))
     {
         day = 28;
     }
     return new YearMonthDay(year, month, day);
 }
 internal override YearMonthDay SetYear(YearMonthDay yearMonthDay, int year)
 {
     int month = yearMonthDay.Month;
     int day = yearMonthDay.Day;
     // The only value which might change day is the last day of a leap year
     if (month == 12 && day == 30 && !IsLeapYear(year))
     {
         day = 29;
     }
     return new YearMonthDay(year, month, day);
 }
Пример #5
0
 public void AllYears()
 {
     // Range of years we actually care about. We support more, but that's okay.
     for (int year = -9999; year <= 9999; year++)
     {
         var ymd = new YearMonthDay(year, 5, 20);
         Assert.AreEqual(year, ymd.Year);
         Assert.AreEqual(5, ymd.Month);
         Assert.AreEqual(20, ymd.Day);
     }
 }
Пример #6
0
 public void AllMonths()
 {
     // We'll never actually need 16 months, but we support that many...
     for (int month = 1; month < 16; month++)
     {
         var ymd = new YearMonthDay(-123, month, 20);
         Assert.AreEqual(-123, ymd.Year);
         Assert.AreEqual(month, ymd.Month);
         Assert.AreEqual(20, ymd.Day);
     }
 }
Пример #7
0
 public void AllDays()
 {
     // We'll never actually need 64 days, but we support that many...
     for (int day = 1; day < 64; day++)
     {
         var ymd = new YearMonthDay(-123, 12, day);
         Assert.AreEqual(-123, ymd.Year);
         Assert.AreEqual(12, ymd.Month);
         Assert.AreEqual(day, ymd.Day);
     }
 }
        internal override YearMonthDay AddMonths(YearMonthDay yearMonthDay, int months)
        {
            if (months == 0)
            {
                return yearMonthDay;
            }
            // Get the year and month
            int thisYear = yearMonthDay.Year;
            int thisMonth = yearMonthDay.Month;

            // Do not refactor without careful consideration.
            // Order of calculation is important.

            int yearToUse;
            // Initially, monthToUse is zero-based
            int monthToUse = thisMonth - 1 + months;
            if (monthToUse >= 0)
            {
                yearToUse = thisYear + (monthToUse / monthsInYear);
                monthToUse = (monthToUse % monthsInYear) + 1;
            }
            else
            {
                yearToUse = thisYear + (monthToUse / monthsInYear) - 1;
                monthToUse = Math.Abs(monthToUse);
                int remMonthToUse = monthToUse % monthsInYear;
                // Take care of the boundary condition
                if (remMonthToUse == 0)
                {
                    remMonthToUse = monthsInYear;
                }
                monthToUse = monthsInYear - remMonthToUse + 1;
                // Take care of the boundary condition
                if (monthToUse == 1)
                {
                    yearToUse++;
                }
            }
            // End of do not refactor.

            // Quietly force DOM to nearest sane value.
            int dayToUse = yearMonthDay.Day;
            int maxDay = GetDaysInMonth(yearToUse, monthToUse);
            dayToUse = Math.Min(dayToUse, maxDay);
            return new YearMonthDay(yearToUse, monthToUse, dayToUse);
        }
 public void GetYearMonthDay_YearAndDayOfYear()
 {
     var calculator = new UmAlQuraYearMonthDayCalculator();
     for (int year = calculator.MinYear; year <= calculator.MaxYear; year++)
     {
         int dayOfYear = 1;
         for (int month = 1; month <= 12; month++)
         {
             for (int day = 1; day <= calculator.GetDaysInMonth(year, month); day++)
             {
                 var actual = calculator.GetYearMonthDay(year, dayOfYear);
                 var expected = new YearMonthDay(year, month, day);
                 Assert.AreEqual(expected, actual, "year={0}; dayOfYear={1}", year, dayOfYear);
                 dayOfYear++;
             }
         }
     }
 }
 public void GetYearMonthDay_DaysSinceEpoch()
 {
     var calculator = new UmAlQuraYearMonthDayCalculator();
     int daysSinceEpoch = calculator.GetStartOfYearInDays(calculator.MinYear);
     for (int year = calculator.MinYear; year <= calculator.MaxYear; year++)
     {
         for (int month = 1; month <= 12; month++)
         {
             for (int day = 1; day <= calculator.GetDaysInMonth(year, month); day++)
             {
                 var actual = calculator.GetYearMonthDay(daysSinceEpoch);
                 var expected = new YearMonthDay(year, month, day);
                 Assert.AreEqual(expected, actual, "daysSinceEpoch={0}", daysSinceEpoch);
                 daysSinceEpoch++;
             }
         }
     }
 }
Пример #11
0
        public void TestDayOfYear()
        {
            YearMonthDay nonLeapBeforeEndOfFeb = new YearMonthDay(2006, 2, 15);
            Assert.AreEqual(46, nonLeapBeforeEndOfFeb.DayOfYear);

            YearMonthDay nonLeapAfterEndOfFeb = new YearMonthDay(2006, 3, 14);
            Assert.AreEqual(73, nonLeapAfterEndOfFeb.DayOfYear);

            YearMonthDay leapBeforeEndOfFeb = new YearMonthDay(2008, 2, 15);
            Assert.AreEqual(46, leapBeforeEndOfFeb.DayOfYear);

            YearMonthDay leapAfterEndOfFeb = new YearMonthDay(2008, 3, 14);
            Assert.AreEqual(74, leapAfterEndOfFeb.DayOfYear);
        }
Пример #12
0
 public void TestConstructWithInvalidDate()
 {
     YearMonthDay ymd = new YearMonthDay(2006, 2, 29);
 }
 public override int Compare(YearMonthDay lhs, YearMonthDay rhs)
 {
     // The civil month numbering system allows a naive comparison.
     if (monthNumbering == HebrewMonthNumbering.Civil)
     {
         return lhs.CompareTo(rhs);
     }
     // Otherwise, try one component at a time. (We could benchmark this
     // against creating a new pair of YearMonthDay values in the civil month numbering,
     // and comparing them...)
     int yearComparison = lhs.Year.CompareTo(rhs.Year);
     if (yearComparison != 0)
     {
         return yearComparison;
     }
     int lhsCivilMonth = CalendarToCivilMonth(lhs.Year, lhs.Month);
     int rhsCivilMonth = CalendarToCivilMonth(rhs.Year, rhs.Month);
     int monthComparison = lhsCivilMonth.CompareTo(rhsCivilMonth);
     if (monthComparison != 0)
     {
         return monthComparison;
     }
     return lhs.Day.CompareTo(rhs.Day);
 }
        // 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(YearMonthDay minuendDate, YearMonthDay subtrahendDate)
        {
            // First (quite rough) guess... we could probably be more efficient than this, but it's unlikely to be very far off.
            int minuendCivilMonth = CalendarToCivilMonth(minuendDate.Year, minuendDate.Month);
            int subtrahendCivilMonth = CalendarToCivilMonth(subtrahendDate.Year, subtrahendDate.Month);
            double minuendTotalMonths = minuendCivilMonth + (minuendDate.Year * MonthsPerLeapCycle) / (double) YearsPerLeapCycle;
            double subtrahendTotalMonths = subtrahendCivilMonth + (subtrahendDate.Year * MonthsPerLeapCycle) / (double) YearsPerLeapCycle;
            int diff = (int) (minuendTotalMonths - subtrahendTotalMonths);

            if (Compare(subtrahendDate, minuendDate) <= 0)
            {
                // Go backwards until we've got a tight upper bound...
                while (Compare(AddMonths(subtrahendDate, diff), minuendDate) > 0)
                {
                    diff--;
                }
                // Go forwards until we've overshot
                while (Compare(AddMonths(subtrahendDate, diff), minuendDate) <= 0)
                {
                    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 (Compare(AddMonths(subtrahendDate, diff), minuendDate) < 0)
                {
                    diff++;
                }
                // Go backwards until we've overshot
                while (Compare(AddMonths(subtrahendDate, diff), minuendDate) >= 0)
                {
                    diff--;
                }
                // Take account of the overshoot
                return diff + 1;
            }
        }
Пример #15
0
 public void TestGetHashCode()
 {
     YearMonthDay ymd1 = new YearMonthDay(2006, 3, 14);
     YearMonthDay ymd2 = new YearMonthDay(2006, 3, 14);
     YearMonthDay ymd3 = new YearMonthDay(2006, 5, 26);
     Assert.AreEqual(ymd1.GetHashCode(), ymd2.GetHashCode());
     Assert.AreNotEqual(ymd1.GetHashCode(), ymd3.GetHashCode());
 }
Пример #16
0
        public void TestRoundTripDefaultConstructed()
        {
            YearMonthDay ymd = new YearMonthDay();
            YearMonthDay ymd2 = new YearMonthDay(ymd.JulianDayNumber);

            Assert.AreEqual(ymd, ymd2);
        }
 public void GetDaysSinceEpoch()
 {
     var calculator = new HebrewYearMonthDayCalculator(HebrewMonthNumbering.Scriptural);
     var unixEpoch = new YearMonthDay(5730, 10, 23);
     Assert.AreEqual(0, calculator.GetDaysSinceEpoch(unixEpoch));
 }
Пример #18
0
 public void TestJulianDayNumber()
 {
     const int astronomicalJulianDayNumber = 2454959;
     YearMonthDay ymd = new YearMonthDay(astronomicalJulianDayNumber);
     Assert.AreEqual(astronomicalJulianDayNumber, ymd.JulianDayNumber);
 }
Пример #19
0
        public void TestCompareToObject()
        {
            YearMonthDay ymd1 = new YearMonthDay(2006, 3, 14);
            object ymd4 = new YearMonthDay(2004, 2, 21);

            Assert.IsTrue(ymd1.CompareTo(null) > 0);
            Assert.IsTrue(ymd1.CompareTo(ymd4) > 0);
        }
Пример #20
0
        public void TestConstructFromDayOfYear()
        {
            int[] years = { 2000, 2001 };

            Assert.IsTrue(YearMonthDay.IsLeapYear(years[0]));
            Assert.IsFalse(YearMonthDay.IsLeapYear(years[1]));

            foreach (int year in years)
            {
                int cumulativeDays = 0;
                for (int month = 1; month <= 12; ++month)
                {
                    // Test first of the month.
                    YearMonthDay ymd = new YearMonthDay(year, cumulativeDays + 1);
                    Assert.AreEqual(year, ymd.Year);
                    Assert.AreEqual(month, ymd.Month);
                    Assert.AreEqual(1, ymd.Day);

                    int daysInMonth = YearMonthDay.DaysInMonth(year, month);

                    // Test last of the month.
                    ymd = new YearMonthDay(year, cumulativeDays + daysInMonth);
                    Assert.AreEqual(year, ymd.Year);
                    Assert.AreEqual(month, ymd.Month);
                    Assert.AreEqual(daysInMonth, ymd.Day);

                    cumulativeDays += daysInMonth;
                }
            }
        }
Пример #21
0
        public void TestConstructFromJulianDate()
        {
            DateTime dt = new DateTime(2008, 10, 23, 12, 0, 0);
            JulianDate jd = new JulianDate(dt);

            YearMonthDay ymd = new YearMonthDay(jd);
            Assert.AreEqual(2008, ymd.Year);
            Assert.AreEqual(10, ymd.Month);
            Assert.AreEqual(23, ymd.Day);

            dt = new DateTime(2008, 10, 23, 0, 0, 0);
            jd = new JulianDate(dt);

            ymd = new YearMonthDay(jd);
            Assert.AreEqual(2008, ymd.Year);
            Assert.AreEqual(10, ymd.Month);
            Assert.AreEqual(23, ymd.Day);

            dt = new DateTime(2008, 10, 23, 23, 59, 59);
            jd = new JulianDate(dt);

            ymd = new YearMonthDay(jd);
            Assert.AreEqual(2008, ymd.Year);
            Assert.AreEqual(10, ymd.Month);
            Assert.AreEqual(23, ymd.Day);
        }
Пример #22
0
 public void TestToString()
 {
     YearMonthDay ymd1 = new YearMonthDay(2006, 3, 14);
     Assert.AreEqual(ymd1.ToString(), "2006:3:14");
 }
Пример #23
0
        public void TestEquality()
        {
            YearMonthDay first = new YearMonthDay(2000, 1, 1);
            YearMonthDay second = new YearMonthDay(2000, 1, 1);
            Assert.AreEqual(first, second);
            Assert.IsTrue(first.Equals(second));
            Assert.IsTrue(second.Equals(first));
            Assert.AreEqual(0, first.CompareTo(second));
            Assert.AreEqual(0, second.CompareTo(first));

            second = new YearMonthDay(2001, 1, 1);
            Assert.AreNotEqual(first, second);
            Assert.IsFalse(first.Equals(second));
            Assert.IsFalse(second.Equals(first));
            Assert.AreNotEqual(0, first.CompareTo(second));
            Assert.AreNotEqual(0, second.CompareTo(first));

            second = new YearMonthDay(2000, 2, 1);
            Assert.AreNotEqual(first, second);
            Assert.IsFalse(first.Equals(second));
            Assert.IsFalse(second.Equals(first));
            Assert.AreNotEqual(0, first.CompareTo(second));
            Assert.AreNotEqual(0, second.CompareTo(first));

            second = new YearMonthDay(2000, 1, 2);
            Assert.AreNotEqual(first, second);
            Assert.IsFalse(first.Equals(second));
            Assert.IsFalse(second.Equals(first));
            Assert.AreNotEqual(0, first.CompareTo(second));
            Assert.AreNotEqual(0, second.CompareTo(first));

            Assert.AreNotEqual(first, 5);
        }
Пример #24
0
        public void TestDefaultConstructedIsValid()
        {
            YearMonthDay ymd = new YearMonthDay();
            YearMonthDay ymd2 = new YearMonthDay(ymd.Year, ymd.Month, ymd.Day);

            Assert.AreEqual(ymd, ymd2);
            Assert.AreEqual(ymd.DayOfWeek, ymd2.DayOfWeek);
            Assert.AreEqual(ymd.DayOfYear, ymd2.DayOfYear);
        }
Пример #25
0
 public void TestRetainValue()
 {
     YearMonthDay date = new YearMonthDay(2000, 1, 1);
     Assert.AreEqual(2000, date.Year);
     Assert.AreEqual(1, date.Month);
     Assert.AreEqual(1, date.Day);
 }
Пример #26
0
        public void TestComparisons()
        {
            YearMonthDay ymd1 = new YearMonthDay(2006, 3, 14);
            YearMonthDay ymd2 = new YearMonthDay(2006, 3, 14);
            YearMonthDay ymd3 = new YearMonthDay(2006, 5, 26);
            object ymd4 = new YearMonthDay(2004, 2, 21);

            Assert.IsTrue(ymd1 == ymd2);
            Assert.IsTrue(ymd2 == ymd1);
            Assert.IsTrue(ymd1 != ymd3);
            Assert.IsTrue(ymd1 >= ymd2);
            Assert.IsTrue(ymd1 <= ymd2);
            Assert.IsTrue(ymd1.CompareTo(ymd2) == 0);
            Assert.IsTrue(ymd2 < ymd3);
            Assert.IsTrue(ymd2 <= ymd3);
            Assert.IsTrue(ymd3 > ymd2);
            Assert.IsTrue(ymd3 >= ymd2);
            Assert.AreNotEqual(ymd1, ymd4);
        }
 internal override int GetDaysSinceEpoch(YearMonthDay yearMonthDay) =>
     // Just inline the arithmetic that would be done via various methods.
     GetStartOfYearInDays(yearMonthDay.Year)
            + (yearMonthDay.Month - 1) * DaysInMonth
            + (yearMonthDay.Day - 1);
        internal override YearMonthDay AddMonths(YearMonthDay yearMonthDay, 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 yearMonthDay;
            }
            int year = yearMonthDay.Year;
            int month = CalendarToCivilMonth(year, yearMonthDay.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 >= GetMonthsInYear(year))
                {
                    months -= GetMonthsInYear(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 -= GetMonthsInYear(year) - month;
                // Subtract a year at a time
                while (months + GetMonthsInYear(year) <= 0)
                {
                    months += GetMonthsInYear(year);
                    year--;
                }
                // However many months we've got left to add (which will still be negative...)
                // tells us the final month.
                month = GetMonthsInYear(year) + months;
            }

            // Convert back to calendar month
            month = CivilToCalendarMonth(year, month);
            int day = Math.Min(GetDaysInMonth(year, month), yearMonthDay.Day);
            return new YearMonthDay(year, month, day);
        }
Пример #29
0
        public void TestDayOfWeek()
        {
            YearMonthDay ymd = new YearMonthDay(2009, 06, 10);
            Assert.AreEqual(DayOfWeek.Wednesday, ymd.DayOfWeek);

            ymd = new YearMonthDay(2009, 06, 11);
            Assert.AreEqual(DayOfWeek.Thursday, ymd.DayOfWeek);
        }
Пример #30
0
 public void TestCompareToWrongType()
 {
     YearMonthDay ymd = new YearMonthDay(2006, 3, 14);
     ymd.CompareTo(5);
 }