如何查找多个年份而不只是一个年份的复活节日期?

时间:2019-04-10 13:55:17

标签: java

到目前为止,我有一个代码可以计算输入一年的复活节的日期。我需要对其进行更改,以便为您提供多年的多个日期(您输入2年而不是介于两者之间的所有日期)。希望有道理!

我不确定我要在这里做什么。我们已经学习了forloops(注意:我们只是在学习Java),所以我尝试为代码放一个forloop,但是由于我不确定这样做是如何实现的,所以简短了。

import java.util.Scanner;

public static void main(String[] args) {
    System.out.print("Please enter a year to calculate Easter Sunday\n>");
    Scanner sc = new Scanner(System.in);//imports java.util.Scanner to the library
    int aNumber = sc.nextInt();//saves next inputted number as "aNumber"

    while (aNumber <=0){//while statement to make sure inputted year is positive
        System.out.println("Please enter a postive year: ");
        aNumber = sc.nextInt();

    }

    int a = aNumber % 19,
        b = aNumber / 100,
        c = aNumber % 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, //determines month as a number
        date = (h - m + r + month + 19) % 32;//determines date

    String test;
    switch(month)//switch case to convert "month" to a string 
    {
        case 1:
            test = "January ";
            break;
        case 2:
            test = "February ";
            break;
        case 3:
            test = "March ";
            break;
        case 4:
            test = "April ";
            break;
        case 5:
            test = "May ";
            break;
        case 6:
            test = "June ";
            break;
        case 7:
            test = "July ";
            break;
        case 8:
            test = "August ";
            break;
        case 9:
            test = "September ";
            break;
        case 10:
            test = "October ";
            break;
        case 11:
            test = "November ";
            break;
        case 12:
            test = "December ";
            break;
        default:
            test = "error";
    }
    System.out.println("In " + aNumber + ", Easter Sunday will be on " + test + "" + date  + ".");//displays year,date and month of Easter Sunday
}

我打算在您输入的两年之间每年获得多个日期。

2 个答案:

答案 0 :(得分:1)

好吧,只要您的代码可以正确计算复活节,就可以针对以下目标:

static String printEasterFor(int aNumber) {
        int a = aNumber % 19,
                b = aNumber / 100,
                c = aNumber % 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, //determines month as a number
                date = (h - m + r + month + 19) % 32;//determines date

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

        return "In " + aNumber + ", Easter Sunday will be on " + test + "" + date  + ".";//displays year,date and month of Easter Sunday
    }


    static List<String> showEasterBetween(int start, int end) {
        List<String> result = new ArrayList<>();
        IntStream.range(start, end).forEach(year -> result.add(printEasterFor(year)));

        return result;
    }

然后您这样称呼:

public static void main(String[] args) {
    int startYear = 2005;
    int endYear = 2025;
    List<String> easters = showEasterBetween(startYear, endYear);
}

作为改进,您的方法printEasterFor可以返回LocalDate对象,而不是打印字符串,但我希望您能理解。

答案 1 :(得分:1)

java.time

Answer by mate00似乎正确。如此处所述,您应该使用 java.time 类型。让我们采用其他答案中所示的代码,并使其与现代的日期时间类更加完美。为了清楚起见,我们还更改了一些名称。

我们有一个Year类。使用该Year类型作为方法的参数使代码更具自记录性。

Year year = Year.of( 2019 ) ; 

我们有LocalDate表示仅日期的值,没有日期和时区。

LocalDate localDate = LocalDate.of( 2019 , Month.JANUARY , 23 ) ;

我们有一个Month枚举,为一年的每个月预定义一个对象。使用Month枚举,我们可以将您长的switch语句折叠成一两行。 Month.values()方法生成一个由枚举预实例化的所有对象的数组。我们可以按数字从该数组中选择一个月。但是我们必须使用恼人的从零开始的索引计数。从1-12减去1得到0-11。

Month month = Month.values()[ 1-1 ];  // Get `Month.JANUARY` object for month number 1 (index number 0). 

示例代码

这里是一个完整的示例类Easter,其中有一对方法重载of(经过一年或两年)。给定已建立的java.time naming conventions,也许forYearforYears可能是更好的方法名称。理想名称为for,但这是for循环的保留关键字。

当心:我尚未测试此代码的结果。使用风险自负。

package work.basil.example;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import java.time.*;

public class Easter
{

    static LocalDate of ( Year year )
    {
        int yearNumber = year.getValue(); // Convert from object to simple integer.
        int a = yearNumber % 19,
                b = yearNumber / 100,
                c = yearNumber % 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,
                monthNumber = ( h - m + r + 90 ) / 25, //determines month as a number
                dayOfMonth = ( h - m + r + monthNumber + 19 ) % 32;//determines date

        int monthIndex = ( monthNumber - 1 ); // Convert from ordinal number to index number, zero-based for accessing an array in Java.
        Month month = Month.values()[ monthIndex ];  // Get the `Month` enum object for this month index. Throws an exception if the month index is out of range of 0-11.

        LocalDate easter = LocalDate.of( yearNumber , month , dayOfMonth );
        return easter;
    }

    static List < LocalDate > of ( Year start , Year stop )
    {
        Objects.requireNonNull( start );
        Objects.requireNonNull( stop );
        if ( stop.isBefore( start ) )  // Verify the stop year is not before the start year. Defensive programming. 
        {
            throw new IllegalArgumentException( "The stop year cannot be before the start year. Message # 296232f7-0c6e-49c2-a462-851aa0b30352." );
        }
        List < LocalDate > easters = new ArrayList <>();
        Year year = start;
        while ( year.isBefore( stop ) )
        {
            LocalDate easter = Easter.of( year );  // Determine the date of Easter for this particular year.
            easters.add( easter );
            // Prepare for next loop.
            year = year.plusYears( 1L );  // Increment to the next year in succession.
        }

        return easters;
    }

    public static void main ( String[] args )
    {
        List < LocalDate > easters = Easter.of( Year.of( 2005 ) , Year.of( 2010 ) );
        System.out.println( "easters.toString(): " + easters );
    }
}

运行时。

  

easters.toString():[2005-03-27、2006-04-16、2007-04-08、2008-03-23、2009-04-12]

在此特定例程中,我们真的不需要Month枚举。我们可以将monthNumber整数传递给工厂方法LocalDate::of

LocalDate easter = LocalDate.of( yearNumber , monthNumber , dayOfMonth );

字符串

要生成表示这些LocalDate对象值的字符串,请使用DateTimeFormatter类,尤其是其ofLocalizedDate方法。搜索堆栈溢出以获取更多信息,因为已经有很多次了。

DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL ).withLocale( Locale.CANADA_FRENCH) ;  // Or `Locale.US` etc.
String output = localDate.format( f ) ;
  

dimanche 2005年3月27日