/// <summary> /// This method can be used to calculate the Easter Sunday date using one of three methods defined by /// <see cref="EasterMethod"/>. /// </summary> /// <remarks>See the <see cref="EasterMethod"/> enumerated type for the ways in which Easter Sunday can /// be calculated. A number of days can be added to or subtracted from the returned date to find other /// Easter related dates (i.e. subtract two from the returned date to get the date on which Good Friday /// falls).</remarks> /// <param name="year">The year in which to calculate Easter</param> /// <param name="method">The method to use for calculating Easter</param> /// <returns>The date on which Easter falls in the specified year as calculated using the specified /// method.</returns> /// <exception cref="ArgumentOutOfRangeException">An exception is thrown if the year is not between 1583 /// and 4099 for the Orthodox and Gregorian methods or if the year is less than 326 for the Julian /// method.</exception> /// <example> /// <code language="cs"> /// // Returns 04/11/2004 for Easter /// dtEaster = DateUtils.EasterSunday(2004, EasterMethod.Gregorian); /// /// // Calculate Good Friday from that date /// dtGoodFriday = dtEaster.AddDays(-2); /// </code> /// <code language="vbnet"> /// ' Returns 04/11/2004 for Easter /// dtEaster = DateUtils.EasterSunday(2004, EasterMethod.Gregorian) /// /// ' Calculate Good Friday from that date /// dtGoodFriday = dtEaster.AddDays(-2) /// </code> /// </example> public static DateTime EasterSunday(int year, EasterMethod method) { int century, yearRem, temp, pfm, tabc, day, month; // Validate year if (method == EasterMethod.Julian && year < 326) { throw new ArgumentOutOfRangeException("year", year, LR.GetString("ExDUBadJulianYear")); } if (method != EasterMethod.Julian && (year < 1583 || year > 4099)) { throw new ArgumentOutOfRangeException("year", year, LR.GetString("ExDUBadOrthGregYear")); } century = year / 100; // Get century yearRem = year % 19; // Get remainder of year / 19 if (method != EasterMethod.Gregorian) { // Calculate PFM date (Julian and Orthodox) pfm = ((225 - 11 * yearRem) % 30) + 21; // Find the next Sunday temp = year % 100; day = pfm + ((20 - ((pfm - 19) % 7) - ((40 - century) % 7) - ((temp + (temp / 4)) % 7)) % 7) + 1; // Convert Julian to Gregorian date for Orthodox method if (method == EasterMethod.Orthodox) { // Ten days were skipped in the Gregorian calendar from October 5-14, 1582 day += 10; // Only one in every four century years are leap years in the Gregorian calendar. Every // century is a leap year in the Julian calendar. if (year > 1600) { day += (century - 16 - ((century - 16) / 4)); } } } else { // Calculate PFM date (Gregorian) temp = ((century - 15) / 2) + 202 - (11 * yearRem); switch (century) { case 21: case 24: case 25: case 27: case 28: case 29: case 30: case 31: case 32: case 34: case 35: case 38: temp--; break; case 33: case 36: case 37: case 39: case 40: temp -= 2; break; default: break; } temp %= 30; pfm = temp + 21; if (temp == 29 || (temp == 28 && yearRem > 10)) { pfm--; } // Find the next Sunday tabc = (40 - century) % 4; if (tabc == 3) { tabc++; } if (tabc > 1) { tabc++; } temp = year % 100; day = pfm + ((20 - ((pfm - 19) % 7) - tabc - ((temp + (temp / 4)) % 7)) % 7) + 1; } // Return the date if (day > 61) { day -= 61; month = 5; // Can occur in May for EasterMethod.Orthodox } else if (day > 31) { day -= 31; month = 4; } else { month = 3; } return(new DateTime(year, month, day)); }
/// <summary> /// This method can be used to calculate the Easter Sunday date using one of three methods defined by /// <see cref="EasterMethod"/>. /// </summary> /// <remarks>See the <see cref="EasterMethod"/> enumerated type for the ways in which Easter Sunday can /// be calculated. A number of days can be added to or subtracted from the returned date to find other /// Easter related dates (i.e. subtract two from the returned date to get the date on which Good Friday /// falls).</remarks> /// <param name="year">The year in which to calculate Easter</param> /// <param name="method">The method to use for calculating Easter</param> /// <returns>The date on which Easter falls in the specified year as calculated using the specified /// method.</returns> /// <exception cref="ArgumentOutOfRangeException">An exception is thrown if the year is not between 1583 /// and 4099 for the Orthodox and Gregorian methods or if the year is less than 326 for the Julian /// method.</exception> /// <example> /// <code language="cs"> /// // Returns 04/11/2004 for Easter /// dtEaster = DateUtils.EasterSunday(2004, EasterMethod.Gregorian); /// /// // Calculate Good Friday from that date /// dtGoodFriday = dtEaster.AddDays(-2); /// </code> /// <code language="vbnet"> /// ' Returns 04/11/2004 for Easter /// dtEaster = DateUtils.EasterSunday(2004, EasterMethod.Gregorian) /// /// ' Calculate Good Friday from that date /// dtGoodFriday = dtEaster.AddDays(-2) /// </code> /// </example> public static DateTime EasterSunday(int year, EasterMethod method) { int century, yearRem, temp, pfm, tabc, day, month; // Validate year if(method == EasterMethod.Julian && year < 326) throw new ArgumentOutOfRangeException("year", year, LR.GetString("ExDUBadJulianYear")); if(method != EasterMethod.Julian && (year < 1583 || year > 4099)) throw new ArgumentOutOfRangeException("year", year, LR.GetString("ExDUBadOrthGregYear")); century = year / 100; // Get century yearRem = year % 19; // Get remainder of year / 19 if(method != EasterMethod.Gregorian) { // Calculate PFM date (Julian and Orthodox) pfm = ((225 - 11 * yearRem) % 30) + 21; // Find the next Sunday temp = year % 100; day = pfm + ((20 - ((pfm - 19) % 7) - ((40 - century) % 7) - ((temp + (temp / 4)) % 7)) % 7) + 1; // Convert Julian to Gregorian date for Orthodox method if(method == EasterMethod.Orthodox) { // Ten days were skipped in the Gregorian calendar from October 5-14, 1582 day += 10; // Only one in every four century years are leap years in the Gregorian calendar. Every // century is a leap year in the Julian calendar. if(year > 1600) day += (century - 16 - ((century - 16) / 4)); } } else { // Calculate PFM date (Gregorian) temp = ((century - 15) / 2) + 202 - (11 * yearRem); switch(century) { case 21: case 24: case 25: case 27: case 28: case 29: case 30: case 31: case 32: case 34: case 35: case 38: temp--; break; case 33: case 36: case 37: case 39: case 40: temp -= 2; break; default: break; } temp %= 30; pfm = temp + 21; if(temp == 29 || (temp == 28 && yearRem > 10)) pfm--; // Find the next Sunday tabc = (40 - century) % 4; if(tabc == 3) tabc++; if(tabc > 1) tabc++; temp = year % 100; day = pfm + ((20 - ((pfm - 19) % 7) - tabc - ((temp + (temp / 4)) % 7)) % 7) + 1; } // Return the date if(day > 61) { day -= 61; month = 5; // Can occur in May for EasterMethod.Orthodox } else if(day > 31) { day -= 31; month = 4; } else month = 3; return new DateTime(year, month, day); }
/// <summary> /// Load the data grid with all Easter Sunday dates for the specified range of years /// </summary> /// <param name="sender">The sender of the event</param> /// <param name="e">The event arguments</param> private void btnEaster_Click(object sender, EventArgs e) { int fromYear, toYear, year; string desc; EasterMethod em = EasterMethod.Gregorian; fromYear = (int)udcFromYear.Value; toYear = (int)udcToYear.Value; if (rbJulian.Checked) { em = EasterMethod.Julian; } else if (rbOrthodox.Checked) { em = EasterMethod.Orthodox; } // Adjust years as necessary based on the method if (em != EasterMethod.Julian) { if (fromYear < 1583) { fromYear = 1583; } if (fromYear > 4099) { fromYear = 4099; } if (toYear < 1583) { toYear = 1583; } if (toYear > 4099) { toYear = 4099; } } else { if (fromYear < 326) { fromYear = 326; } if (toYear < 326) { toYear = 326; } } if (fromYear > toYear) { year = fromYear; fromYear = toYear; toYear = year; } udcFromYear.Value = fromYear; udcToYear.Value = toYear; this.Cursor = Cursors.WaitCursor; // Create the grid view's data source List <ListItem> items = new List <ListItem>(); desc = String.Format("Easter ({0})", em.ToString()); while (fromYear <= toYear) { items.Add(new ListItem(DateUtils.EasterSunday(fromYear++, em), desc)); } dgvDatesFound.DataSource = items; this.Cursor = Cursors.Default; }