暂时解决这个问题,会喜欢一些意见。
我想要解决的问题收集一个特定日期的所有日期,例如,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);
}
答案 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)
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标准将星期一定义为week的第一天,由数字1标识。星期日是7。
与java捆绑在一起的java.util.Date和.Calendar类非常麻烦。避免他们。它们已在Java 8中被新的java.time包取代。该套餐的灵感来自Joda-Time,这是一个具有一定优势的活跃可行项目。
默认情况下,Joda-Time和java.time都使用ISO 8601。
对于这个问题,我们只需要日期,而不是时间或时区。 Joda-Time和java.time都为此提供了一个LocalDate类。
使用Year.of
和LocalDate::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 syntax。 LocalDate::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 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和&amp; SimpleDateFormat
要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
现在位于Joda-Time的maintenance mode项目建议迁移到java.time类。
您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
从哪里获取java.time类?
ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 2 :(得分:0)
我认为你的主要问题在于这种情况
if (currentDayOfWeek >= dayOfWeek) {
因为那将会计算出更高的&#34;更高的&#34;比你想要的那一天。如果您通过3
,它也会计算高于3
的任何一天,这不是您想要的。
条件应该是
if (currentDayOfWeek == dayOfWeek) {
我还建议您使用Calendar getTime method而不是解析String
来获取Date
。