/// <summary> /// Sets the GregorianCalendar change date. This is the point when the switch /// from Julian dates to Gregorian dates occurred. Default is October 15, /// 1582. Previous to this, dates will be in the Julian calendar. /// <p> /// To obtain a pure Julian calendar, set the change date to /// <c>Date(Long.MAX_VALUE)</c>. To obtain a pure Gregorian calendar, /// set the change date to <c>Date(Long.MIN_VALUE)</c>. /// </summary> /// /// <param name="date">the given Gregorian cutover date.</param> /// @stable ICU 2.0 public void SetGregorianChange(DateTime date) { gregorianCutover = (date.Ticks / 10000); // If the cutover has an extreme value, then create a pure // Gregorian or pure Julian calendar by giving the cutover year and // JD extreme values. if (gregorianCutover <= IBM.ICU.Util.Calendar.MIN_MILLIS) { gregorianCutoverYear = cutoverJulianDay = Int32.MinValue; } else if (gregorianCutover >= IBM.ICU.Util.Calendar.MAX_MILLIS) { gregorianCutoverYear = cutoverJulianDay = Int32.MaxValue; } else { // Precompute two internal variables which we use to do the actual // cutover computations. These are the Julian day of the cutover // and the cutover year. cutoverJulianDay = (int)IBM.ICU.Util.Calendar.FloorDivide(gregorianCutover, IBM.ICU.Util.Calendar.ONE_DAY); // Convert cutover millis to extended year GregorianCalendar cal = new GregorianCalendar(GetTimeZone()); cal.SetTime(date); gregorianCutoverYear = cal.Get(IBM.ICU.Util.Calendar.EXTENDED_YEAR); } }
/// <summary> /// Compute the month and date on which this holiday falls in the year /// containing the date "date". First figure out which date Easter lands on /// in this year, and then add the offset for this holiday to get the right /// date. /// <p> /// The algorithm here is taken from the <a /// href="http://www.faqs.org/faqs/calendars/faq/">Calendar FAQ</a>. /// </summary> /// private DateTime ComputeInYear(DateTime date, GregorianCalendar cal) { if (cal == null) { cal = calendar; } lock (cal) { cal.SetTime(date); int year = cal.Get(IBM.ICU.Util.Calendar.YEAR); int g = year % 19; // "Golden Number" of year - 1 int i = 0; // # of days from 3/21 to the Paschal full moon int j = 0; // Weekday (0-based) of Paschal full moon if (ILOG.J2CsMapping.Util.DateUtil.After(cal.GetTime(), cal.GetGregorianChange())) { // We're past the Gregorian switchover, so use the Gregorian // rules. int c = year / 100; int h = (c - c / 4 - (8 * c + 13) / 25 + 19 * g + 15) % 30; i = h - (h / 28) * (1 - (h / 28) * (29 / (h + 1)) * ((21 - g) / 11)); j = (year + year / 4 + i + 2 - c + c / 4) % 7; } else { // Use the old Julian rules. i = (19 * g + 15) % 30; j = (year + year / 4 + i) % 7; } int l = i - j; int m = 3 + (l + 40) / 44; // 1-based month in which Easter falls int d = l + 28 - 31 * (m / 4); // Date of Easter within that month cal.Clear(); cal.Set(IBM.ICU.Util.Calendar.ERA, IBM.ICU.Util.GregorianCalendar.AD); cal.Set(IBM.ICU.Util.Calendar.YEAR, year); cal.Set(IBM.ICU.Util.Calendar.MONTH, m - 1); // 0-based cal.Set(IBM.ICU.Util.Calendar.DATE, d); cal.GetTime(); // JDK 1.1.2 bug workaround cal.Add(IBM.ICU.Util.Calendar.DATE, daysAfterEaster); return(cal.GetTime()); } }