计算复活节星期日的日期

时间:2014-09-24 16:43:02

标签: java math

编写一个程序来计算复活节星期日的日期。复活节星期日是春天第一个满月后的第一个星期天。 使用数学家Carl Friedrich Gauss在1800年发明的算法:

  1. y成为年份(例如1800或2001年)
  2. y除以19并调用余下的a。忽略商。
  3. y除以100以获得商b和其余c
  4. b除以4以获得商d和其余e
  5. 8 * b + 13除以25以获得商g。忽略其余部分。
  6. 19 * a + b - d - g + 15除以30以获得余额h。忽视 商。
  7. c除以4以获得商j和其余k
  8. a + 11 * h除以319以获得商m。忽略其余部分。
  9. 2 * e + 2 * j - k - h + m + 32除以7以获得余额r。忽略商。
  10. h - m + r + 90除以25以获得商n。忽略了 其余部分。
  11. h - m + r + n + 19除以32,以获得剩余的p。忽略了 商。
  12. 然后复活节属于p个月的n天。

    例如,如果y是2001:

    a = 6
    b = 20
    c = 1
    d = 5
    e = 0
    g = 6
    h = 18
    j = 0
    k = 1
    m = 0
    r = 6
    n = 4
    p = 15
    

    因此,在2001年,复活节星期日在4月15日下降。

    确保提示用户一年并让用户输入年份。另外,请确保使用描述值输出的相应消息输出p和n的值。


    我把它放到Java代码中有点麻烦。这是我尝试过的:

    import java.util.Scanner;
    
    
    
    public class Easter {
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
    
            int y = 2014;
            int a = y % 19;
            int b = y / 100;
            int c = y % 100;
            int d = b / 4;
            int e = b % 4;
            int g = (8 * b + 13) / 25;
            int h = (19 * a + b - d - g + 15) % 30;
            int j = c / 4;
            int k = c % 4;
            int m = (a + 11 * h) / 319;
            int r = (2 * e + 2 * j - k - h + m + 32) % 7;
            int n = (h - m + r + 90) / 25;
            int p = (h - m + r + n + 19) % 32;
    
            getEasterSundayMonth = n;
            System.out.println("Month: " + Easter.getEasterSundayMonth());
        }
    }
    

    这就是我所拥有的。我不知道如何分配内容,比如我试图让getEasterSundayMonth等于n的值,非常确定它不对。我从哪里开始?

6 个答案:

答案 0 :(得分:8)

试试这个:

import java.util.Scanner;

class Easter
{
    public static void main(String[] args)
    {
        System.out.print("Please enter a year to calculate Easter Sunday\n>");
        Scanner s = new Scanner(System.in);
        int inputted = getResult(s);
        while(inputted <= 0)
        {
            System.out.print("Expected a positive year. Please try again:\n>");
            inputted = getResult(s);
        }
        System.out.println(getEasterSundayDate(inputted));
    }

    private static int getResult(Scanner s)
    {
        while(!s.hasNextInt())
        {
            System.out.print("Expected a valid year. Please try again:\n>");
            s.nextLine();
        }
        return s.nextInt();
    }

    public static String getEasterSundayDate(int year)
    {
        int a = year % 19,
            b = year / 100,
            c = year % 100,
            d = b / 4,
            e = b % 4,
            g = (8 * b + 13) / 25,
            h = (19 * a + b - d - g + 15) % 30,
            j = c / 4,
            k = c % 4,
            m = (a + 11 * h) / 319,
            r = (2 * e + 2 * j - k - h + m + 32) % 7,
            n = (h - m + r + 90) / 25,
            p = (h - m + r + n + 19) % 32;

        String result;
        switch(n)
        {
            case 1:
                result = "January ";
                break;
            case 2:
                result = "February ";
                break;
            case 3:
                result = "March ";
                break;
            case 4:
                result = "April ";
                break;
            case 5:
                result = "May ";
                break;
            case 6:
                result = "June ";
                break;
            case 7:
                result = "July ";
                break;
            case 8:
                result = "August ";
                break;
            case 9:
                result = "September ";
                break;
            case 10:
                result = "October ";
                break;
            case 11:
                result = "November ";
                break;
            case 12:
                result = "December ";
                break;
            default:
                result = "error";
        }

        return result + p;
    }
}

输入2001会导致April 15作为输出。

答案 1 :(得分:4)

你离计划不起作用还远远不够。你还有两件事需要做。

  • 提示用户一年
  • 输出找到的日期

使用Scanner提示用户输入的技巧是创建一个while循环来测试用户输入的每一行,并不断重复直到它看到合法值。

而不是硬编码y = 2014;(或其他),你想做这样的事情:

Scanner input = new Scanner(System.in);
int y = -1;  // No easter back in B.C.
while (y < 0) {
    System.out.println("Please enter a year (integer greater than zero)");
    if (input.hasNextInt()) {    // check to see if the user entered a number
        y = input.nextInt();     // if so, read it
    }
    input.nextLine();            // advance the scanner to the next line of input
}

在这种情况下,每次用户输入数字时,y仍为-1并且循环继续。

您已经正确地进行了所有计算,因此要结束您的计划,您只需要输出月/日。

我不打算尝试将计算提取到辅助方法中。只需在main()

中直接使用计算值即可
int a = y % 19;
int b = y / 100;
...
int n = (h - m + r + 90) / 25;
int p = (h - m + r + n + 19) % 32;
System.out.println("In the year " + y + " Easter with fall on day " + p + " of month " + n);

答案 2 :(得分:1)


VisualBasic Excel VBA Code

Function Easter_Sunday(Year)
    k = Int(Year / 100)                                         'the secular number
    s = 2 - Int((3 * k + 3) / 4)                                'the secular sun control
    m = 15 + Int((3 * k + 3) / 4) - Int((8 * k + 13) / 25)      'the secular moon circuit
    a = Year Mod 19                                             'the lunar parameter
    d = (19 * a + m) Mod 30                                     'the seed for the first full moon in spring
    r = Int(d / 29) + (Int(d / 28) - Int(d / 29)) * Int(a / 11) 'the calendar correction amount
    EB = 21 + d - r                                             'the Easter border
    FS = 7 - (Year + Int(Year / 4) + s) Mod 7                   'the first Sunday in March
    ED = 7 - (EB - FS) Mod 7                                    'Easter distance in days
    ESM = EB + ED - 1                                           'the date of Easter Sunday as the March date

    '--------------------------------------- "For Years (1900-9999)" ------------------------------
    Easter_Sunday = DateValue(1 & "." & 3 & "." & Year) + ESM

    '--------------------------------------- "or for all Years" -----------------------------------
    Month_ = 3 + Int(ESM / 31)               'Month March or April
    ES = 1 + ESM Mod 31                      'Eastersunday

    Easter_Sunday = ("Su, " & Year & "." & Format(Month_, "00") & "." & Format(ES, "00"))

End Function

答案 3 :(得分:0)

万一有人在Typescript中寻找算法的更新版本(NY Anonymous Gregorian)...

easterDate() {
  var currentYear = new Date().getFullYear();
  var a = Math.floor(currentYear % 19);
  var b = Math.floor(currentYear / 100);
  var c = Math.floor(currentYear % 100);
  var d = Math.floor(b / 4);
  var e = Math.floor(b % 4);
  var f = Math.floor((b + 8) / 25);
  var g = Math.floor((b - f + 1) / 3);
  var h = Math.floor((19 * a + b - d - g + 15) % 30);
  var i = Math.floor(c / 4);
  var k = Math.floor(c % 4);
  var l = Math.floor((32 + 2 * e + 2 * i - h - k) % 7);
  var m = Math.floor((a + 11 * h + 22 * l) / 451);
  var n = Math.floor((h + l - 7 * m + 114) / 31);
  var p = Math.floor(((h + l - 7 * m + 114) % 31) + 1);
  // console.log('a: ' + a + ' b: ' + b + ' c: ' + c + ' d: ' + d + ' e: ' + e);
  // console.log('f: ' + f + ' g: ' + g + ' h: ' + h + ' i: ' + i + ' k: ' + k);
  // console.log('l: ' + l + ' m: ' + m + ' n: ' + n + ' p: ' + p);
  // console.log("In the year " + currentYear + " Easter with fall on day " + p + " of month " + n);
  var month = n.toString();
  while (month.length < 2) month = "0" + month;
  var day = p.toString();
  while (day.length < 2) day = "0" + day;
  var dateString = currentYear.toString() + '-' + month + '-' + day + 'T00:00:00';
  return new Date(dateString);
}

答案 4 :(得分:0)

...或者在ColdFusion中需要它:

<!---
    Function to get the easter date adopted to ColdFusion as of
    https://stackoverflow.com/questions/26022233/calculate-the-date-of-easter-sunday
--->
<cffunction name="getEasterDate">
    <cfargument name="year" required="true">
    <cfscript>

        var currentYear = arguments["year"];

        var a = floor(currentYear % 19);
        var b = floor(currentYear / 100);
        var c = floor(currentYear % 100);
        var d = floor(b / 4);
        var e = floor(b % 4);
        var f = floor((b + 8) / 25);
        var g = floor((b - f + 1) / 3);
        var h = floor((19 * a + b - d - g + 15) % 30);
        var i = floor(c / 4);
        var k = floor(c % 4);
        var l = floor((32 + 2 * e + 2 * i - h - k) % 7);
        var m = floor((a + 11 * h + 22 * l) / 451);
        var n = floor((h + l - 7 * m + 114) / 31);
        var p = floor(((h + l - 7 * m + 114) % 31) + 1);

        var month = n;
        if (len(month) lt 2) {
            month = "0" & month;
        } 

        var day = p;
        if (len(day) lt 2) {
            day = "0" & day;
        }

        var dateString = day & '.' & month & '.' & currentYear;

        return dateString;

    </cfscript>
</cffunction>

答案 5 :(得分:0)

/**
 * Orthodox easter formula, invented back in 1800 by famous Carl Friedrich Gauss.
 */
public static LocalDate getEasterSundayDate(int year) {
    int a = year % 19,
            b = year / 100,
            c = year % 100,
            d = b / 4,
            e = b % 4,
            g = (8 * b + 13) / 25,
            h = (19 * a + b - d - g + 15) % 30,
            j = c / 4,
            k = c % 4,
            m = (a + 11 * h) / 319,
            r = (2 * e + 2 * j - k - h + m + 32) % 7,
            month = (h - m + r + 90) / 25,
            day = (h - m + r + month + 19) % 32;

    return LocalDate.of( year, month, day );
}