拉出一年中特定日期的所有日期 - Java

时间:2014-09-03 17:15:32

标签: java date

暂时解决这个问题,会喜欢一些意见。

我想要解决的问题收集一个特定日期的所有日期,例如,2014年的每个星期二。日期存储在ArrayList<Date>中。然后返回此列表。

还必须验证以确保年份不为0且提交的星期几必须是1-7之间的数字。

如果有任何问题,我很想知道我搞砸了什么。

public List<Date> getDatesforDayOfWeek(int year, int dayOfWeek) throws InvalidDateException, ParseException {

    List<Date> dateList = new ArrayList<>();

    if (year <= 0 || (1 > dayOfWeek && dayOfWeek > 7)) {

        throw new InvalidDateException("Year or day of week is invalid.");

    } else {

        Calendar newCal = Calendar.getInstance();
        newCal.set(YEAR, year);
        newCal.set(DAY_OF_YEAR, 1);



        while (newCal.get(YEAR) < year + 1) {

            int currentDayOfWeek = newCal.get(DAY_OF_WEEK);

            Date newDate = null;
            if (currentDayOfWeek >= dayOfWeek) {

                int dayOfMonth = newCal.get(DAY_OF_MONTH);
                String strDayOfMonth = String.valueOf(dayOfMonth);
                String strYear = String.valueOf(year);

                DateUtility d1 = new DateUtility();
                Date passDate = newCal.getTime();

                String weekDay = d1.getWeekDayNameAbbreviation(passDate);
                String monthAbbreviation = d1.getMonthAbbreviation(passDate);


                String finalString = new String();

                finalString.concat(weekDay).concat(" ").
                        concat(monthAbbreviation).concat(" ").
                        concat(strDayOfMonth).concat(" ").
                        concat(strYear);

                SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd YYYY");
                Date theDate = format.parse(finalString);

                dateList.add(theDate);
            }
            newCal.add(Calendar.DATE, 1);
        }

    }
    return (dateList);
}

3 个答案:

答案 0 :(得分:1)

您的问题未能指明哪一周是第一天的哪一天,但是您的方法测试当天的当前日期会使事情变得更加复杂。让我们从使用Calendar标准

验证一周中的几天开始
private static boolean isValidDayOfWeek(int dayOfWeek) {
    switch (dayOfWeek) {
    // Seven days of the week.
    case Calendar.SUNDAY: case Calendar.MONDAY: case Calendar.TUESDAY: 
    case Calendar.WEDNESDAY: case Calendar.THURSDAY: case Calendar.FRIDAY:
    case Calendar.SATURDAY:
        return true;
    }
    return false;
}

然后我们可以做类似的事情,

public static List<Date> getDatesforDayOfWeek(int year, int dayOfWeek) {
    List<Date> dateList = new ArrayList<>();
    if (year <= 0 || !isValidDayOfWeek(dayOfWeek)) {
        return null;
    } else {
        Calendar newCal = Calendar.getInstance();
        newCal.set(Calendar.YEAR, year);
        newCal.set(Calendar.DAY_OF_YEAR, 1);
        // First, let's loop until we're at the correct day of the week.
        while (newCal.get(Calendar.DAY_OF_WEEK) != dayOfWeek) {
            newCal.add(Calendar.DAY_OF_MONTH, 1);
        }
        // Now, add the Date to the List. Then add a week and loop (stop
        // when the year changes).
        do {
            dateList.add(newCal.getTime());
            newCal.add(Calendar.DAY_OF_MONTH, 7);
        } while (newCal.get(Calendar.YEAR) == year);
    }
    return dateList;
}

main()离开我们。因此,为了获得2014年的每个星期二,您可以使用 -

public static void main(String[] args) {
    List<Date> tuesdays = getDatesforDayOfWeek(2014, Calendar.TUESDAY);
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    for (Date d : tuesdays) {
        System.out.println(df.format(d));
    }
}

答案 1 :(得分:1)

TL;博士

startOfYear                                              // `Year.of( 2019 ).atDay( 1 )` gets the first day of the year.
.datesUntil( startOfYear.plusYears( 1 ) )                // Generate a stream of incrementing `LocalDate` objects.
.filter(                                                 // Pull out the dates that are a Tuesday.
    t -> t.getDayOfWeek().equals( DayOfWeek.TUESDAY ) 
)
.collect( Collectors.toList() )                          // Return results in a `List` of `LocalDate` objects.

ISO 8601

日期工作的ISO 8601标准将星期一定义为week的第一天,由数字1标识。星期日是7。

避免j.u.Date&amp; .Calendar

与java捆绑在一起的java.util.Date和.Calendar类非常麻烦。避免他们。它们已在Java 8中被新的java.time包取代。该套餐的灵感来自Joda-Time,这是一个具有一定优势的活跃可行项目。

默认情况下,Joda-Time和java.time都使用ISO 8601

日期 - 仅

对于这个问题,我们只需要日期,而不是时间或时区。 Joda-Time和java.time都为此提供了一个LocalDate类。

java.time

使用Year.ofLocalDate::plusYears来确定一年的边界,每个第一天产生一对LocalDate个对象。

LocalDate startOfYear = Year.of( 2019 ).atDay( 1 );  // Determine first day of the year.
LocalDate startOfFollowingYear = startOfYear.plusYears( 1 );

循环,一次递增一天的日期。如果该日期恰好是星期二,请将其添加到我们的收藏中。

LocalDate localDate = startOfYear;
List < LocalDate > tuesdays = new ArrayList <>( 55 ); // Set initialCapacity to maximum number of tuesdays in a year. Probably 53, but I'll go with 55 for good measure.
while ( localDate.isBefore( startOfFollowingYear ) )
{
    if ( localDate.getDayOfWeek().equals( DayOfWeek.TUESDAY ) )
    {
        tuesdays.add( localDate );
    }
    // Set up the next loop.
    localDate = localDate.plusDays( 1 );
}
System.out.println( tuesdays );

请参阅此code run live at IdeOne.com

  

[2019-01-01,2019-01-08,2019-01-15,2019-01-22,2019-01-29,2019-02-05,2019-02-12,2019-02- 19,2019-02-26,2019-03-05,2019-03-12,2019-03-19,2019-03-26,2019-04-02,2019-04-09,2019-04-16, 2019-04-23,2019-04-30,2019-05-07,2019-05-14,2019-05-21,2019-05-28,2019-06-04,2019-06-11,2019- 06-18,2019-06-25,2019-07-02,2019-07-09,2019-07-16,2019-07-23,2019-07-30,2019-08-06,2019-08- 13,2019-08-20,2019-08-27,2019-09-03,2019-09-10,209-09-17,2019-09-24,2019-10-01,2019-10-08, 2019-10-15,2019-10-22,2019-10-29,2019-11-05,2019-11-12,2019-11-19,2019-11-26,2019-12-03,2019- 12-10,2019-12-17,2019-12-24,2019-12-31]

或者看中functional lambda syntaxLocalDate::datesUntil方法在Java 9及更高版本中生成stream。然后通过DayOfWeek.TUESDAY上的匹配过滤流。

LocalDate startOfYear = Year.of( 2019 ).atDay( 1 );
Stream < LocalDate > stream = startOfYear.datesUntil( startOfYear.plusYears( 1 ) );
List < LocalDate > tuesdays = stream.filter( t -> t.getDayOfWeek().equals( DayOfWeek.TUESDAY ) ).collect( Collectors.toList() );

约达-时间

以下是Joda-Time 2.4中用于收集一年中所有星期二的一些示例代码。

int year = 2014; 
String input = year + "-01-01";
LocalDate localDateInput = LocalDate.parse( input );
LocalDate firstTuesday = localDateInput.withDayOfWeek ( DateTimeConstants.TUESDAY );
LocalDate tuesday = firstTuesday;  // for incrementing by week.
List<LocalDate> list = new ArrayList<>();
while ( tuesday.getYear() == year ) {
  list.add( tuesday );
  tuesday.plusWeeks( 1 );
}

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和&amp; SimpleDateFormat

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 2 :(得分:0)

我认为你的主要问题在于这种情况

if (currentDayOfWeek >= dayOfWeek) {

因为那将会计算出更高的&#34;更高的&#34;比你想要的那一天。如果您通过3,它也会计算高于3的任何一天,这不是您想要的。

条件应该是

if (currentDayOfWeek == dayOfWeek) {

我还建议您使用Calendar getTime method而不是解析String来获取Date