예제 #1
0
 private static int GetResult(DateBuffer result, int part)
 {
     return(part switch
     {
         DatePartYear => result.year,
         DatePartMonth => result.month,
         DatePartDay => result.day,
         _ => throw new InvalidOperationException(SR.InvalidOperation_DateTimeParsing),
     });
예제 #2
0
        /// <summary>
        /// Using the Hebrew table (HebrewTable) to get the Hebrew month/day value for Gregorian January 1st
        /// in a given Gregorian year.
        /// Greogrian January 1st falls usually in Tevet (4th month). Tevet has always 29 days.
        /// That's why, there no nead to specify the lunar month in the table.  There are exceptions, and these
        /// are coded by giving numbers above 29 and below 1.
        /// Actual decoding is takenig place in the switch statement below.
        /// </summary>
        /// <returns>
        /// The Hebrew year type. The value is from 1 to 6.
        /// normal years : 1 = 353 days   2 = 354 days   3 = 355 days.
        /// Leap years   : 4 = 383        5   384        6 = 385 days.
        /// </returns>
        internal static int GetLunarMonthDay(int gregorianYear, DateBuffer lunarDate)
        {
            //  Get the offset into the LunarMonthLen array and the lunar day
            //  for January 1st.
            int index = gregorianYear - FirstGregorianTableYear;

            if (index < 0 || index > TableSize)
            {
                throw new ArgumentOutOfRangeException(nameof(gregorianYear));
            }

            index        *= 2;
            lunarDate.day = s_hebrewTable[index];

            // Get the type of the year. The value is from 1 to 6
            int lunarYearType = s_hebrewTable[index + 1];

            //  Get the Lunar Month.
            switch (lunarDate.day)
            {
            case 0:                       // 1/1 is on Shvat 1
                lunarDate.month = 5;
                lunarDate.day   = 1;
                break;

            case 30:                      // 1/1 is on Kislev 30
                lunarDate.month = 3;
                break;

            case 31:                      // 1/1 is on Shvat 2
                lunarDate.month = 5;
                lunarDate.day   = 2;
                break;

            case 32:                      // 1/1 is on Shvat 3
                lunarDate.month = 5;
                lunarDate.day   = 3;
                break;

            case 33:                      // 1/1 is on Kislev 29
                lunarDate.month = 3;
                lunarDate.day   = 29;
                break;

            default:                          // 1/1 is on Tevet (This is the general case)
                lunarDate.month = 4;
                break;
            }

            return(lunarYearType);
        }
예제 #3
0
        private static int GetResult(DateBuffer result, int part)
        {
            switch (part)
            {
            case DatePartYear:
                return(result.year);

            case DatePartMonth:
                return(result.month);

            case DatePartDay:
                return(result.day);
            }

            throw new InvalidOperationException(SR.InvalidOperation_DateTimeParsing);
        }
예제 #4
0
        /// <summary>
        /// Convert Hebrew date to Gregorian date.
        ///  The algorithm is like this:
        ///     The hebrew year has an offset to the Gregorian year, so we can guess the Gregorian year for
        ///     the specified Hebrew year.  That is, GreogrianYear = HebrewYear - FirstHebrewYearOf1AD.
        ///
        ///     From the Gregorian year and HebrewTable, we can get the Hebrew month/day value
        ///     of the Gregorian date January 1st.  Let's call this month/day value [hebrewDateForJan1]
        ///
        ///     If the requested Hebrew month/day is less than [hebrewDateForJan1], we know the result
        ///     Gregorian date falls in previous year.  So we decrease the Gregorian year value, and
        ///     retrieve the Hebrew month/day value of the Gregorian date january 1st again.
        ///
        ///     Now, we get the answer of the Gregorian year.
        ///
        ///     The next step is to get the number of days between the requested Hebrew month/day
        ///     and [hebrewDateForJan1].  When we get that, we can create the DateTime by adding/subtracting
        ///     the ticks value of the number of days.
        /// </summary>
        private static DateTime HebrewToGregorian(int hebrewYear, int hebrewMonth, int hebrewDay, int hour, int minute, int second, int millisecond)
        {
            // Get the rough Gregorian year for the specified hebrewYear.
            int gregorianYear = hebrewYear - HebrewYearOf1AD;

            DateBuffer hebrewDateOfJan1 = new DateBuffer(); // year value is unused.
            int        lunarYearType    = GetLunarMonthDay(gregorianYear, hebrewDateOfJan1);

            if ((hebrewMonth == hebrewDateOfJan1.month) && (hebrewDay == hebrewDateOfJan1.day))
            {
                return(new DateTime(gregorianYear, 1, 1, hour, minute, second, millisecond));
            }

            int days = GetDayDifference(lunarYearType, hebrewMonth, hebrewDay, hebrewDateOfJan1.month, hebrewDateOfJan1.day);

            DateTime gregorianNewYear = new DateTime(gregorianYear, 1, 1);

            return(new DateTime(gregorianNewYear.Ticks + days * TicksPerDay + TimeToTicks(hour, minute, second, millisecond)));
        }
예제 #5
0
        /// <summary>
        /// Returns a given date part of this DateTime. This method is used
        /// to compute the year, day-of-year, month, or day part.
        /// </summary>
        internal virtual int GetDatePart(long ticks, int part)
        {
            // The Gregorian year, month, day value for ticks.
            int  gregorianYear, gregorianMonth, gregorianDay;
            int  hebrewYearType;              // lunar year type
            long AbsoluteDate;                // absolute date - absolute date 1/1/1600

            // Make sure we have a valid Gregorian date that will fit into our
            // Hebrew conversion limits.
            CheckTicksRange(ticks);

            DateTime time = new DateTime(ticks);

            // Save the Gregorian date values.
            time.GetDatePart(out gregorianYear, out gregorianMonth, out gregorianDay);

            DateBuffer lunarDate = new DateBuffer();    // lunar month and day for Jan 1

            // From the table looking-up value of HebrewTable[index] (stored in lunarDate.day), we get the
            // lunar month and lunar day where the Gregorian date 1/1 falls.
            lunarDate.year = gregorianYear + HebrewYearOf1AD;
            hebrewYearType = GetLunarMonthDay(gregorianYear, lunarDate);

            // This is the buffer used to store the result Hebrew date.
            DateBuffer result = new DateBuffer();

            //  Store the values for the start of the new year - 1/1.
            result.year  = lunarDate.year;
            result.month = lunarDate.month;
            result.day   = lunarDate.day;

            //  Get the absolute date from 1/1/1600.
            AbsoluteDate = GregorianCalendar.GetAbsoluteDate(gregorianYear, gregorianMonth, gregorianDay);

            //  If the requested date was 1/1, then we're done.
            if ((gregorianMonth == 1) && (gregorianDay == 1))
            {
                return(GetResult(result, part));
            }

            // Calculate the number of days between 1/1 and the requested date.
            long numDays = AbsoluteDate - GregorianCalendar.GetAbsoluteDate(gregorianYear, 1, 1);

            // If the requested date is within the current lunar month, then
            // we're done.
            if ((numDays + (long)lunarDate.day) <= (long)(s_lunarMonthLen[hebrewYearType * MaxMonthPlusOne + lunarDate.month]))
            {
                result.day += (int)numDays;
                return(GetResult(result, part));
            }

            // Adjust for the current partial month.
            result.month++;
            result.day = 1;

            // Adjust the Lunar Month and Year (if necessary) based on the number
            // of days between 1/1 and the requested date.
            // Assumes Jan 1 can never translate to the last Lunar month, which
            // is true.
            numDays -= (long)(s_lunarMonthLen[hebrewYearType * MaxMonthPlusOne + lunarDate.month] - lunarDate.day);
            Debug.Assert(numDays >= 1, "NumDays >= 1");

            // If NumDays is 1, then we are done.  Otherwise, find the correct Hebrew month
            // and day.
            if (numDays > 1)
            {
                // See if we're on the correct Lunar month.
                while (numDays > (long)(s_lunarMonthLen[hebrewYearType * MaxMonthPlusOne + result.month]))
                {
                    // Adjust the number of days and move to the next month.
                    numDays -= (long)(s_lunarMonthLen[hebrewYearType * MaxMonthPlusOne + result.month++]);

                    // See if we need to adjust the Year.
                    // Must handle both 12 and 13 month years.
                    if ((result.month > 13) || (s_lunarMonthLen[hebrewYearType * MaxMonthPlusOne + result.month] == 0))
                    {
                        // Adjust the Year.
                        result.year++;
                        hebrewYearType = s_hebrewTable[(gregorianYear + 1 - FirstGregorianTableYear) * 2 + 1];

                        // Adjust the Month.
                        result.month = 1;
                    }
                }

                // Found the right Lunar month.
                result.day += (int)(numDays - 1);
            }

            return(GetResult(result, part));
        }