Joda Time: How to get dates of weekdays on some date interval?
I have two LocalDates that represent some time interval. Now i have to get LocalDates of all fridays, that t开发者_开发问答his interval contains. Easiest way to do it?
package org.life.java.so.questions;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
/**
*
* @author Jigar
*/
public class JodaTimeDateTraverseQuestion {
public static void main(String[] args) {
DateTime startDt = new DateTime(2010,12,1,0,0,0,0);//1st Dec 2010
DateTime endDt = new DateTime(2010,12,31,0,0,0,0);//31st Dec 2010
DateTime tempDate = new DateTime(startDt.getMillis());
while(tempDate.compareTo(endDt) <=0 ){
if(tempDate.getDayOfWeek() != DateTimeConstants.SATURDAY && tempDate.getDayOfWeek() != DateTimeConstants.SUNDAY){
System.out.println(""+tempDate);
}
tempDate = tempDate.plusDays(1);
}
}
}
Solution: lazily step by one week.
import org.joda.time.LocalDate;
import java.util.Iterator;
public class DayOfWeekIterator implements Iterator<LocalDate>{
private final LocalDate end;
private LocalDate nextDate;
public DayOfWeekIterator(LocalDate start, LocalDate end, int dayOfWeekToIterate){
this.end = end;
nextDate = start.withDayOfWeek(dayOfWeekToIterate);
if (start.getDayOfWeek() > dayOfWeekToIterate) {
nextDate = nextDate.plusWeeks(1);
}
}
public boolean hasNext() {
return !nextDate.isAfter(end);
}
public LocalDate next() {
LocalDate result = nextDate;
nextDate = nextDate.plusWeeks(1);
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
Test
import org.joda.time.DateTimeConstants;
import org.joda.time.LocalDate;
public class DayOfWeekIteratorTest {
public static void main(String[] args) {
LocalDate startDate = new LocalDate(2010, 12, 1);//1st Dec 2010
LocalDate endDate = new LocalDate(2010, 12, 31);//31st Dec 2010
DayOfWeekIterator it = new DayOfWeekIterator(startDate, endDate, DateTimeConstants.FRIDAY);
while (it.hasNext()) {
System.out.println(it.next());
}
}
}
tl;dr
java.time.LocalDate.of( 2018 , Month.JANUARY , 23 ) // A date-only class in the modern *java.time* classes that supplant both Joda-Time and the troublesome old date-time classes.
.with(
TemporalAdjusters.next( DayOfWeek.FRIDAY ) // Nifty `TemporalAdjuster` implementation for moving to another date. Immutable Objects pattern means a new object is returned based on the original which remains unmodified.
)
.isBefore( // Compare `LocalDate` objects with `isBefore`, `isAfter`, and `isEqual`.
LocalDate.of( 2018 , Month.FEBRUARY , 27 );
)
java.time
FYI, the Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes.
Define your stop & start LocalDate
objects.
LocalDate start = LocalDate.of( 2018 , Month.JANUARY , 23 );
LocalDate stop = LocalDate.of( 2018 , Month.FEBRUARY , 27 );
// TODO: Verify start.isBefore( stop ).
Collect the Friday dates we find. You might optimize a bit by sizing the collection.
// Pre-size the collection.
int initialCapacity = ( int ) ( ChronoUnit.WEEKS.between( start , stop ) + 2 ); // Adding two for good measure.
List < LocalDate > fridays = new ArrayList <>( initialCapacity );
Determine the first Friday, using the start date if it is itself a Friday. Use a pair of TemporalAdjuster
implementations offered in the TemporalAdjusters
class: next(DayOfWeek)
& nextOrSame(DayOfWeek)
. Pass the desired day-of-week via the DayOfWeek
enum, seven pre-defined objects, one for each day of the week Monday-Sunday.
LocalDate friday = start.with( TemporalAdjusters.nextOrSame( DayOfWeek.FRIDAY ) );
while ( friday.isBefore( stop ) )
{
fridays.add( friday ); // Remember this Friday date.
// Setup next loop.
friday = friday.with( TemporalAdjusters.next( DayOfWeek.FRIDAY ) );
}
System.out.println( "From " + start + " to " + stop + " = " + fridays );
From 2018-01-23 to 2018-02-27 = [2018-01-26, 2018-02-02, 2018-02-09, 2018-02-16, 2018-02-23]
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes.
Where to obtain the java.time classes?
- Java SE 8, Java SE 9, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.time classes.
- For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
精彩评论