查找指定年份中给定工作日的出现次数

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

我正在尝试编写一个带有两个参数的程序:工作日和年份。 然后,程序应打印出用户指定的工作日位于给定年份中每个月的第一天的次数。 我可以做一个月,但我如何迭代所有十二个月。

这是我的代码:

public class dateCheck {

public static void main(String[] args) {

    String weekday="Sunday";
    int year=2017;

 Calendar cal = Calendar.getInstance();
     cal.set(Calendar.DATE, 01);
     cal.set(Calendar.MONTH, Calendar.JANUARY);
     cal.set(Calendar.YEAR, year);

     cal.set(Calendar.DAY_OF_MONTH, 1);
     Date firstDayOfMonth = cal.getTime();  

     DateFormat sdf = new SimpleDateFormat("EEEEEEEE");   
     System.out.println("First Day of Month: " + sdf.format(firstDayOfMonth));

     if(weekday.equals(sdf.format(firstDayOfMonth))){
         System.out.println("This day falls on the first of the month");
     }
     else
         System.out.println("This day does not fall on the first of the month");


    }


}

我想我可以使用 for 循环,但我不知道如何迭代几个月。 我是 Java 新手。 任何帮助表示赞赏。谢谢。

java datetime
7个回答
5
投票

如果您能够使用 Java 8,就没有理由继续使用

Calendar
。这是使用 新日期和时间 api 的版本:

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.TextStyle;
import java.util.Locale;

public class WeekdayCheck {

    public static void main(String[] args) {
        String weekday = "Sunday";
        int year = 2017;
        int occurrences = 0;

        for (Month month : Month.values()) {
            LocalDate date = LocalDate.of(year, month, 1);
            DayOfWeek dayOfWeek = date.getDayOfWeek();
            if (dayOfWeek.getDisplayName(TextStyle.FULL, Locale.ENGLISH).equals(weekday)) {
                occurrences++;
            }
        }

        System.out.println(weekday + " is the first day of a month " + occurrences + " times in " + year);
    }
}

更新:

初始版本使用

dayOfWeek.getDisplayName
是为了符合你的比较。更明智的选择(如评论中指出的)是将用户输入也转换为
DayOfWeek
实例。

这是一种修改后的方法,目前适用于“sunday”、“Sunday”或“sUnDaY”等输入,但可以通过增强

toDayOfWeek
方法进行调整以实现更复杂的逻辑:

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;

public class WeekdayCheck {

    public static void main(String[] args) {
        String userInput = "Sunday";
        DayOfWeek inputDayOfWeek = toDayOfWeek(userInput);
        int inputYear = 2017;
        int occurrences = 0;

        for (Month month : Month.values()) {
            LocalDate date = LocalDate.of(inputYear, month, 1);
            DayOfWeek dayOfWeek = date.getDayOfWeek();
            if (dayOfWeek == inputDayOfWeek) {
                occurrences++;
            }
        }

        System.out.println(userInput + " is the first day of a month " + occurrences + " times in " + inputYear);
    }

    private static DayOfWeek toDayOfWeek(String dayString) {
        return DayOfWeek.valueOf(dayString.toUpperCase());
    }
}

1
投票

这是我的方法。我使用两种方法。一个循环有一个循环遍历所有月份,第二个循环在其中使用,如果条件为真,则返回一个布尔值。条件与用户查找的条件是同一工作日。如果为 true,则字段 counter 增加 1。 我使用 Calendar.set() 方法首先将其设置为年初,然后使用 Calender.roll(),每次迭代提前一个月。 我希望这是有道理的

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class MyCalendar {
    private Calendar calendar;
    private int counter;
    private DateFormat frm;

    public static void main(String[] args) {
        MyCalendar cal = new MyCalendar();
        int answer = cal.firstPerMonth(2017, Calendar.SUNDAY);
        System.out.println("total" + answer);
    }

    public MyCalendar() {
        calendar = Calendar.getInstance();
        frm = new SimpleDateFormat("yyyy MMM dd 'is a' EEE");
    }

    public int firstPerMonth(int year, int dayOfWeek) {
        counter = 0;
        calendar.set(2017, 0, 1);
        for(int x = 0; x < 12; x++) {
            if(checkIfSameDay(dayOfWeek)) {
                counter++;
            }
            calendar.roll(Calendar.MONTH, 1);
        }
        return counter;
    }

    public boolean checkIfSameDay(int dayOfWeek) {
        if(dayOfWeek == calendar.get(Calendar.DAY_OF_WEEK)) {
            System.out.println(frm.format(calendar.getTime()));
            return true;
        }
        else return false;
    }

}

0
投票

这就是迭代 12 个连续月份的方式(这是因为

Calendar.JANUARY
和所有剩余的月份都是从 0 开始的连续
int

    String weekday = "Sunday";
    int year = 2017;

    for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DATE, 01);
        cal.set(Calendar.MONTH, month);
        cal.set(Calendar.YEAR, year);

        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date firstDayOfMonth = cal.getTime();

        DateFormat sdf = new SimpleDateFormat("EEEEEEEE");
        System.out.println("First Day of Month: " + sdf.format(firstDayOfMonth));

        if (weekday.equals(sdf.format(firstDayOfMonth))) {
            System.out.println("This day falls on the first of the month");
        } else
            System.out.println("This day does not fall on the first of the month");
    }

0
投票

尝试这样的操作:不要传递

Calendar.JANUARY
,而是传递月份的整数值。

public class dateCheck {

    public static void main(String[] args) {

        String weekday = "Sunday";
        int year = 2017;
        int month = 0;

        for (month = 0; month < 12; month++) {
            Calendar cal = Calendar.getInstance();
            cal.set(Calendar.DATE, 01);
            cal.set(Calendar.MONTH, month);
            cal.set(Calendar.YEAR, year);

            cal.set(Calendar.DAY_OF_MONTH, 1);
            Date firstDayOfMonth = cal.getTime();

            DateFormat sdf = new SimpleDateFormat("EEEEEEEE");
            System.out.println("First Day of Month " + month.toString() + ": " + sdf.format(firstDayOfMonth));

            if (weekday.equals(sdf.format(firstDayOfMonth))) {
                System.out.println("This day falls on the first of the month");
            } else
                System.out.println("This day does not fall on the first of the month");
        }

    }


}

0
投票

这种方法使用了

.roll(...)
Calendar
方法。它演示了如何增加
cal
实例。

final static DateFormat sdf = new SimpleDateFormat("EEEEEEEE");

static boolean isOnFirst(String weekday, Calendar month)
{
    String dom = sdf.format(month.getTime());
    return (weekday.equalsIgnoreCase(dom));
}

public static void main(String[] args)
{
    // test data: could be obtained from the user
    String weekday = "Sunday";
    int year = 2017;

    // construct the initial instance
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.DATE, 1);
    cal.set(Calendar.MONTH, Calendar.JANUARY);
    cal.set(Calendar.YEAR, year);

    // our (poorly named) counter for how often it appears
    int num = 0;

    // loop over all of the months in the year
    for (int i = 0; i < 12; ++i) {
        // if we are on the first day of the month, increment our counter
        if (isOnFirst(weekday, cal)) {
            ++num;
        }

        // advance by one month
        cal.roll(Calendar.MONTH, 1);
    }

    // output results
    System.out.println(weekday + " appears " + num 
            + " times on the first day of the month in " + year);
}

输出:

2017 年每月的第一天星期日出现了 2 次


0
投票

试试这个:

   String weekday = "Sunday";
    int year = 2017;

    int numOfWeekDayAsFirstDayInMonth = 0;

    for (int i = 0; i < 11; i++) {

        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DATE, 01);
        cal.set(Calendar.MONTH, i);
        cal.set(Calendar.YEAR, year);

        cal.set(Calendar.DAY_OF_MONTH, 1);
        Date firstDayOfMonth = cal.getTime();

        DateFormat sdf = new SimpleDateFormat("EEEEEEEE");

        if (weekday.equals(sdf.format(firstDayOfMonth))) {
            numOfWeekDayAsFirstDayInMonth++;
        }

    }

    System.out.printf("Week day %s occured %d times in year %s as first day of all monthes", weekday, numOfWeekDayAsFirstDayInMonth, year);

输出:

Week day Sunday occured 2 times in year 2017 as first day of all monthes

0
投票

[Marvin 的回答][1] 是正确的。这是类似的方法,但使用

Stream
Predicate

你说:

两个参数:星期几和年份

使用 java.time 类。

DayOfWeek dow = DayOfWeek.MONDAY ;
Year year = Year.of( 2025 ) ;

每年数量

你说:

指定年份中给定工作日的次数

获取今年的第一个日期。

LocalDate start = year.atDay( 1 ) ;

获取下一年的第一个日期。

LocalDate end = year.plusYears( 1 ).atDay( 1 ) ;

获取

Stream
LocalDate
对象,一年中的每一天都有一个。

Stream < LocalDate > dates = start.datesUntil( end ) ;

筛选符合我们目标星期几的日期。

dates.filter( date -> date.getDayOfWeek().equals( dow ) ) ;

计算一下。这个终端操作执行我们的流。

long count = dates.count() ;

该周某天发生的第一个月的次数

你还说:

该工作日…落在给定年份的每个月的第一天的次数

实际上,我们可以为此扩展上面的代码。添加另一个

Predicate
进行过滤。过滤第一个月的日期。

    LocalDate start = year.atDay( 1 ) ;

Get the first date of the following year.

    LocalDate end = year.plusYears( 1 ).atDay( 1 ) ;

Get a `Stream` of `LocalDate` objects, one for each day of the year.

    start
        .datesUntil( end )
        .filter( date -> date.getDayOfMonth() == 1 )
        .filter( date -> date.getDayOfWeek().equals( dow ) )
        .count() 




  [1]: https://stackoverflow.com/a/44187121/642706
© www.soinside.com 2019 - 2024. All rights reserved.