Есть ли у кого-нибудь хороший алгоритм для расчета какой даты Страстная пятница падает на данный год в качестве входных данных? Предпочтительно в С#.
Как я могу рассчитать, на какую дату выпадает Страстная пятница, учитывая год?
Ответ 1
Вот отличная статья, которая поможет вам построить алгоритм
http://www.codeproject.com/KB/datetime/christianholidays.aspx
На основе этого примера вы должны иметь возможность написать:
DateTime goodFriday = EasterSunday(DateTime.Now.Year).AddDays(-2);
Полный пример:
public static DateTime EasterSunday(int year)
{
int day = 0;
int month = 0;
int g = year % 19;
int c = year / 100;
int h = (c - (int)(c / 4) - (int)((8 * c + 13) / 25) + 19 * g + 15) % 30;
int i = h - (int)(h / 28) * (1 - (int)(h / 28) * (int)(29 / (h + 1)) * (int)((21 - g) / 11));
day = i - ((year + (int)(year / 4) + i + 2 - c + (int)(c / 4)) % 7) + 28;
month = 3;
if (day > 31)
{
month++;
day -= 31;
}
return new DateTime(year, month, day);
}
Ответ 2
Не повторяйте себя
Подумайте
Поймите, что расчет Пасхи - это то, на что вы действительно зависите.
Исследование
Вот официальная страница военно-морской обсерватории для расчета Пасхи.
http://aa.usno.navy.mil/faq/docs/easter.php
Выполнить
Используйте формулу для расчета Пасхи, затем перейдите к предыдущей пятнице (или вычтите 2 дня, подробности до вас).
Ответ 3
Википедия знает: http://en.wikipedia.org/wiki/Good_Friday#Calculating_the_date
Страстная пятница - пятница перед Пасхой, которая по-разному рассчитана на восточное христианство и западное христианство (подробнее см. Computus). Пасха выпадает в первое воскресенье после Пасхальной полнолуния, полной луны или после 21 марта, которая считается датой весеннего равноденствия. Западный расчет использует григорианский календарь, в то время как восточный расчет использует юлианский календарь, чей 21 марта теперь соответствует григорианскому календарю 3 апреля. Расчеты для определения даты полнолуния также различаются. См. Метод знакомства с Пасхой (Астрономическое общество Южной Австралии).
В Восточном христианстве Пасха может падать между 22 марта и 25 апреля по Юлианскому календарю (таким образом, с 4 апреля по 8 мая в соответствии с григорианским календарем в период 1900 и 2099 годов), поэтому Страстная пятница может падать между 20 марта и 23 апреля включительно (или с 2 апреля по 6 мая по григорианскому календарю). (См. Easter.)
Ответ 4
Попробуйте следующее:
// test code:
Console.WriteLine(CalcGoodFri(2008));
Console.WriteLine(CalcGoodFri(2009));
Console.WriteLine(CalcGoodFri(2010));
private static DateTime CalcGoodFri(int yr)
{
//int yr = 2010; // The year for which to determine the date of Good Friday.
int a = yr % 19;
int b = yr / 100;
int c = yr % 100;
int d = b / 4;
int e = b % 4;
int i = c / 4;
int k = c % 4;
int g = (8 * b + 13) / 25;
int h = ((19 * a) + b - d - g + 15) % 30;
int l = ((2 * e) + (2 * i) - k + 32 - h) % 7;
int m = (a + (11*h) + (19*l)) / 433;
int days_to_good_friday = h + l - (7*m) - 2;
int mo = (days_to_good_friday + 90) / 25;
int da = (days_to_good_friday + (33 * mo) + 19) % 32;
return new DateTime ( yr, mo, da) ; // Returns the date of Good Friday
}
Логика портирована отсюда: http://www.kenhamady.com/form25.shtml
Ответ 5
Necromancing.
На самом деле, это зависит от того, является ли это православной или католической Страстной пятницей;)
от https://mycodepad.wordpress.com/2013/04/28/c-calculating-orthodox-and-catholic-easter/
(Примечание: Пасха = Пасхальное воскресенье)
/// <summary>
/// Get Orthodox easter for requested year
/// </summary>
/// <param name="year">Year of easter</param>
/// <returns>DateTime of Orthodox Easter</returns>
public static DateTime GetOrthodoxEaster( int year ) {
int a = year % 19;
int b = year % 7;
int c = year % 4;
int d = (19 * a + 16) % 30;
int e = (2 * c + 4 * b + 6 * d) % 7;
int f = (19 * a + 16) % 30;
int key = f + e + 3;
int month = (key > 30) ? 5 : 4;
int day = (key > 30) ? key - 30 : key;
return new DateTime( year, month, day );
}
/// <summary>
/// Get Catholic easter for requested year
/// </summary>
/// <param name="year">Year of easter</param>
/// <returns>DateTime of Catholic Easter</returns>
public static DateTime GetCatholicEaster( int year ) {
int month = 3;
int G = year % 19 + 1;
int C = year / 100 + 1;
int X = (3 * C) / 4 - 12;
int Y = (8 * C + 5) / 25 - 5;
int Z = (5 * year) / 4 - X - 10;
int E = (11 * G + 20 + Y - X) % 30;
if (E == 24) { E++; }
if ((E == 25) && (G > 11)) { E++; }
int N = 44 - E;
if (N < 21) { N = N + 30; }
int P = (N + 7) - ((Z + N) % 7);
if (P > 31) {
P = P - 31;
month = 4;
}
return new DateTime( year, month, P );
}
Затем вы можете создать абстрактный EasterBunny:
private static void EasterBunnyTest()
{
AbstractEasterBunny WesternEuropeanBunny = new CatholicEasterBunny();
AbstractEasterBunny EasternEuropeanBunny = new OrthodoxEasterBunny();
AbstractEasterBunny LocalizedEasterBunny = AbstractEasterBunny.CreateInstance();
System.DateTime dtRomeEaster = WesternEuropeanBunny.EasterSunday(2016);
System.DateTime dtAthensEaster = EasternEuropeanBunny.EasterSunday(2016);
System.DateTime dtLocalEaster = LocalizedEasterBunny.EasterSunday(2016);
System.Console.WriteLine(dtRomeEaster);
System.Console.WriteLine(dtAthensEaster);
System.Console.WriteLine(dtLocalEaster);
}
С этим абстрактным кроликом здесь:
public abstract class AbstractEasterBunny
{
/// <summary>
/// Gets the Orthodox easter sunday for the requested year
/// </summary>
/// <param name="year">The year you want to know the Orthodox Easter Sunday of</param>
/// <returns>DateTime of Orthodox Easter Sunday</returns>
public abstract System.DateTime EasterSunday(int year);
public abstract System.DateTime GoodFriday(int year);
public static AbstractEasterBunny CreateInstance()
{
System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.CurrentCulture;
System.Globalization.RegionInfo ri = new System.Globalization.RegionInfo(ci.LCID);
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd374073(v=vs.85).aspx
System.Collections.Generic.List<int> lsOrthodox = new System.Collections.Generic.List<int>{
0x10D // Serbia and Montenegro
,0x10E // Montenegro
,0x10F // Serbia
,0x19 // Bosnia and Herzegovina
// ,0x46 // Estonia
// ,0x4B // Czech Republic
// ,0x4D // Finland
,0x62 // Greece
// ,0x6D // Hungary
,0x79 // Iraq
// ,0x8C // Latvia
// ,0x8D // Lithuania
// ,0x8F // Slovakia
// ,0x98 // Moldova
// ,0xD4 // Slovenia
,0x4CA2 // Macedonia, Former Yugoslav Republic of
,0xEB // Turkey
};
// if(ci == WesternSlavonicOrthodox)
if (lsOrthodox.Contains(ri.GeoId))
return new OrthodoxEasterBunny();
// TODO: Correct for Armenia/Georgia ? ? ?
// if(ri.GeoId == 0x7 || ri.GeoId == 0x58) // 0x7: Armenia, 0x58: Georgia
// return new CatholicEasterBunny();
// if(ci == EasternSlavonic)
string strMonthName = ci.DateTimeFormat.GetMonthName(8);
if (System.Text.RegularExpressions.Regex.IsMatch(strMonthName, @"\p{IsCyrillic}"))
{
// there is at least one cyrillic character in the string
return new OrthodoxEasterBunny();
}
return new CatholicEasterBunny();
}
}
public class OrthodoxEasterBunny : AbstractEasterBunny
{
/// <summary>
/// Gets the Orthodox easter sunday for the requested year
/// </summary>
/// <param name="year">The year you want to know the Orthodox Easter Sunday of</param>
/// <returns>DateTime of Orthodox Easter Sunday</returns>
public override System.DateTime EasterSunday(int year)
{
int a = year % 19;
int b = year % 7;
int c = year % 4;
int d = (19 * a + 16) % 30;
int e = (2 * c + 4 * b + 6 * d) % 7;
int f = (19 * a + 16) % 30;
int key = f + e + 3;
int month = (key > 30) ? 5 : 4;
int day = (key > 30) ? key - 30 : key;
return new System.DateTime(year, month, day);
}
public override System.DateTime GoodFriday(int year)
{
return this.EasterSunday(year).AddDays(-2);
}
}
public class CatholicEasterBunny : AbstractEasterBunny
{
/// <summary>
/// Gets the Catholic easter sunday for the requested year
/// </summary>
/// <param name="year">The year you want to know the Catholic Easter Sunday of</param>
/// <returns>DateTime of Catholic Easter Sunday</returns>
public override System.DateTime EasterSunday(int year)
{
int day = 0;
int month = 0;
int g = year % 19;
int c = year / 100;
int h = (c - (int)(c / 4) - (int)((8 * c + 13) / 25) + 19 * g + 15) % 30;
int i = h - (int)(h / 28) * (1 - (int)(h / 28) * (int)(29 / (h + 1)) * (int)((21 - g) / 11));
day = i - ((year + (int)(year / 4) + i + 2 - c + (int)(c / 4)) % 7) + 28;
month = 3;
if (day > 31)
{
month++;
day -= 31;
}
return new System.DateTime(year, month, day);
}
public override System.DateTime GoodFriday(int year)
{
return this.EasterSunday(year).AddDays(-2);
}
}
Ответ 6
Возможно ли использовать конверсии на иврите или арабском лунном календаре? например:
DateTime getEasterSunday(int year)
{
const int fourTeen = 14;
DateTime Paschal = new DateTime(1900, 3, 20);
var iCal = new HebrewCalendar();
DateTime eFullMoon;
var pDate = new DateTime(year, Paschal.Month, Paschal.Day);
var LunarYear = iCal.GetYear(pDate);
var LunarMonth = iCal.GetMonth(pDate);
var LunarDay = iCal.GetDayOfMonth(pDate);
if (LunarDay >= fourTeen) LunarMonth++;
eFullMoon = iCal.ToDateTime(LunarYear, LunarMonth, fourTeen, 0, 0, 0, 0);
return Enumerable.Range(0, 6).Select(x => eFullMoon.Date.AddDays(x)).Where(x => x.DayOfWeek == DayOfWeek.Sunday).First();
}