c# - semana - ¿Cómo puedo calcular en qué fecha cae el Viernes Santo, dado un año?
viernes santo 2020 (6)
¿Alguien tiene un buen algoritmo para calcular en qué fecha cae el Viernes Santo dado el año como aporte? Preferiblemente en C #.
No te repitas
Pensar
Date cuenta de que calcular la Pascua es de lo que realmente dependes.
Investigación
Aquí está la página oficial del Observatorio Naval para calcular la Pascua.
http://aa.usno.navy.mil/faq/docs/easter.php
Ejecutar
Use la fórmula para calcular la Semana Santa y luego cambie al viernes anterior (o reste 2 días, los detalles depende de usted).
¿Es posible utilizar los calendarios lunares hebreo o árabe para la conversión? p.ej:
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();
}
Aquí hay un gran artículo que debería ayudarte a construir tu algoritmo.
http://www.codeproject.com/KB/datetime/christianholidays.aspx
Basado en este ejemplo, deberías poder escribir:
DateTime goodFriday = EasterSunday(DateTime.Now.Year).AddDays(-2);
Ejemplo completo:
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);
}
Nigromancia.
En realidad, depende de si es Viernes Santo ortodoxo o católico;)
de https://mycodepad.wordpress.com/2013/04/28/c-calculating-orthodox-and-catholic-easter/
(Nota: Pascua = Domingo de Pascua)
/// <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 );
}
Entonces todavía podrías crear un EasterBunny abstracto:
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);
}
Con este conejito abstracto aquí:
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);
}
}
Prueba esto:
// 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
}
Lógica portada desde aquí: http://www.kenhamady.com/form25.shtml
Wikipedia sabe: http://en.wikipedia.org/wiki/Good_Friday#Calculating_the_date
El Viernes Santo es el viernes anterior a la Pascua, que se calcula de manera diferente en el cristianismo oriental y en el cristianismo occidental (consulte Computus para obtener más información). La Pascua cae el primer domingo después de la luna llena pascual, la luna llena en o después del 21 de marzo, que se considera la fecha del equinoccio vernal. El cálculo occidental utiliza el calendario gregoriano, mientras que el cálculo oriental utiliza el calendario juliano, cuyo 21 de marzo corresponde ahora al 3 de abril del calendario gregoriano. Los cálculos para identificar la fecha de la luna llena también difieren. Ver método de citas de Pascua (Sociedad Astronómica de Australia del Sur).
En el cristianismo oriental, la Pascua puede caer entre el 22 de marzo y el 25 de abril en el calendario juliano (por lo tanto, entre el 4 de abril y el 8 de mayo en términos del calendario gregoriano, durante el período 1900 y 2099), por lo que el Viernes Santo puede caer entre el 20 de marzo y el 23 de abril. , inclusive (o entre el 2 de abril y el 6 de mayo en términos del calendario gregoriano). (Ver Easter ).