给定一年,我如何计算天主教耶稣受难日是哪一天?

问题描述 投票:0回答:6

有没有人有一个好的算法来计算给定年份作为输入的耶稣受难日是哪一天?最好是 C# 语言。

c# algorithm date date-arithmetic computus
6个回答
73
投票

这是一篇很棒的文章,应该可以帮助您构建算法

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);
}

8
投票

不要重复自己

思考

认识到计算复活节才是你真正依赖的。

研究

这是计算复活节的官方海军天文台页面。

https://web.archive.org/web/20120223154950/https://aa.usno.navy.mil/faq/docs/easter.php

执行

使用计算复活节的公式,然后转到上一个星期五(或减去 2 天,具体由您决定)。


3
投票

试试这个:

// 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


2
投票

维基百科知道:http://en.wikipedia.org/wiki/Good_Friday#Calculate_the_date

耶稣受难日是复活节前的星期五,东方基督教和西方基督教的计算方式不同(详情请参阅Computus)。复活节是复活节满月之后的第一个星期日,满月发生在 3 月 21 日或之后,被视为春分的日期。西方计算使用公历,而东方计算使用儒略历,其中3月21日现在对应于公历的4月3日。确定满月日期的计算也有所不同。请参阅复活节约会方法(南澳大利亚天文学会)。

在东方基督教中,复活节可以在儒略历的3月22日至4月25日之间(因此,在公历1900年至2099年期间,复活节可以在4月4日至5月8日之间),因此耶稣受难日可以在3月20日至4月之间23日(含)(或公历4月2日至5月6日)。 (参见复活节。)


0
投票

死灵术。
实际上,这取决于是东正教还是天主教耶稣受难节;)

来自 https://mycodepad.wordpress.com/2013/04/28/c-calculate-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 );
}

那么你仍然可以创建一个抽象的复活节兔子:

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;
       day = i - ((year + (int)(year / 4) + i + 2 - c + (int)(c / 4)) % 7);

       if (i > 10 && i == (21 - g) && h > 10)
            day -= 7;
        day += 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);
    }

}

0
投票

是否可以使用希伯来阴历或阿拉伯阴历进行转换? 例如:

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();
}
© www.soinside.com 2019 - 2024. All rights reserved.