Java 计算复活节星期日的日期

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26022233/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 01:43:18  来源:igfitidea点击:

Calculate the date of Easter Sunday

javamath

提问by Devin Wesolowski

Write a program to compute the date of Easter Sunday. Easter Sunday is the first Sunday after the first full moon of spring. Use the algorithm invented by the mathematician Carl Friedrich Gauss in 1800:

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

  1. Let ybe the year (such as 1800 or 2001)
  2. Divide yby 19and call the remainder a. Ignore the quotient.
  3. Divide yby 100to get a quotient band a remainder c.
  4. Divide bby 4to get a quotient dand a remainder e.
  5. Divide 8 * b + 13by 25to get a quotient g. Ignore the remainder.
  6. Divide 19 * a + b - d - g + 15by 30to get a remainder h. Ignore the quotient.
  7. Divide cby 4to get a quotient jand a remainder k.
  8. Divide a + 11 * hby 319to get a quotient m. Ignore the remainder.
  9. Divide 2 * e + 2 * j - k - h + m + 32by 7to get a remainder r. Ignore the quotient.
  10. Divide h - m + r + 90by 25to get a quotient n. Ignore the remainder.
  11. Divide h - m + r + n + 19by 32to get a remainder of p. Ignore the quotient.
  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。忽略商。

Then Easter falls on a day pof month n.

然后复活节落在p一个月的某一天n

For example, if y is 2001:

例如,如果 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

Therefore, in 2001, Easter Sunday fell on April 15.

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

Make sure you prompt the user for a year and have the user input the year. Also, make sure you output the values of p and n with the appropriate messages describing the values output.

确保提示用户输入年份并让用户输入年份。此外,请确保使用描述值输出的适当消息输出 p 和 n 的值。



I'm having a little trouble putting this into Java code. Here's what I've tried:

我在将它放入 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());
    }
}

This is what I have. I don't know how to assign stuff, like I tried to get getEasterSundayMonthto equal the value of n, pretty sure its not right. Where do I go from here?

这就是我所拥有的。我不知道如何分配东西,就像我试图获得getEasterSundayMonth等于 的值n,很确定这是不对的。我从这里去哪里?

采纳答案by gparyani

Try this:

尝试这个:

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

An input of 2001results in April 15as the output.

2001结果的输入April 15作为输出。

回答by azurefrog

You aren't far from getting your program working. You really have two things left you need to do.

你离让你的程序工作不远了。你真的还有两件事需要做。

  • Prompt the user for a year
  • Output the date found
  • 提示用户一年
  • 输出找到的日期

The trick to using a Scannerto prompt the user for input is to create a while-loop which tests each line the user enters, and keeps repeating until it sees a legal value.

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

Instead of hard-coding y = 2014;(or whatever), you want to do something like this:

而不是硬编码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
}

in this case, each time the user doesn't enter a number, yremains -1and the loop continues.

在这种情况下,每次用户不输入数字时,都会y保持-1并继续循环。

You are already doing all the calculations correctly, so to end your program, you just need to output the month/day.

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

I wouldn't bother trying to extract the calculation into a helper method. Just use the calculated values directly in main():

我不会费心尝试将计算提取到辅助方法中。只需直接在 中使用计算值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);

回答by AppDreamer

In case anyone is looking for the updated version (NY Anonymous Gregorian) of the algorithm in Typescript...

如果有人在 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);
}

回答by Romi


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

回答by Fips

...or someone needs it in ColdFusion:

...或者有人在 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>