For the current year i.e 2014. Starting from Jan 1st, I have to get the 1st and 3rd Wednesday dates for every month ending, Dec 31st. I am using java version 1.6
I have no idea how to get this.
For the current year i.e 2014. Starting from Jan 1st, I have to get the 1st and 3rd Wednesday dates for every month ending, Dec 31st. I am using java version 1.6
I have no idea how to get this.
Pseudo code, should get you started in jodatime:
LocalDate dt = new LocalDate(2014, 1, 1); // 1st january
for(loop 12 months){
now loop again to find 3rd wednesday
while(count < 4) {
d = d.plusDays(1);
if(d.getDayOfWeek() != DateTimeConstants.WEDNESDAY){
count++
}
// now based on count save in hashmap, 1 = 1st, 3 = 3rd for each month
}
d.plusMonth(1);
}
And here it is in the new java 8 data time :
for(loop through months){
LocalDate date = LocalDate.of(2014, month, 01);
TemporalAdjuster adj = TemporalAdjusters.next(DayOfWeek.WEDNESDAY);
LocalDate nextWed = date.with(adj);
LocalDate secondWed = nextWed.with(adj);
LocalDate thirdWed = secondWed.with(adj);
// save in map
}
Just to answer NimChimpsky's comment to the question. Using the pre-Java8 date and calendar API, here is the solution:
for(int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
GregorianCalendar c = new GregorianCalendar(2014, month, 1);
c.set(Calendar.DAY_OF_WEEK_IN_MONTH, 1);
c.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
System.out.println("First Wednesday: " + c.getTime());
c.set(Calendar.DAY_OF_WEEK_IN_MONTH, 3);
System.out.println("Third Wednesday: " + c.getTime());
System.out.println("---");
}
I haven't actually tried it (the code may be incorrect), but using the new date and time API in Java 8 would be similar:
for(Month month : Month.values()) {
LocalDate ld =
LocalDate.of(2014, month, 1)
.with(ChronoField.ALIGNED_WEEK_OF_MONTH, 1)
.with(ChronoField.DAY_OF_WEEK, DayOfWeek.WEDNESDAY.getValue());
System.out.println("First Wednesday: " + ld);
ld = ld.with(ChronoField.ALIGNED_WEEK_OF_MONTH, 3);
System.out.println("Third Wednesday: " + ld);
System.out.println("---");
}
Here's my take on the problem of collecting first and third Wednesdays of each month of current year.
Note one important difference from the other answers is time zone. Keep in mind that in the wee hours of a new day in Paris, the date in Montréal is still "yesterday", the previous date. So determining the current date requires a time zone.
If you omit the time zone, you get the date according to the JVM’s current default time zone. So your code varies depending on which computer it runs and on what current OS & JVM settings. Better to specify your intended/expected time zone via a DateTimeZone
object defined by a proper time zone name.
Joda-Time (like java.time) offers a LocalDate
class to represent date-only values without any time-of-day or time zone.
Joda-Time can jump to another day of week using the withDayOfWeek
method. That method does not always go forward in time. Following the ISO 8601 standard week of MONDAY to SUNDAY, the method goes back in time if necessary to get prior days that are Monday or later. In our case, that means for any first of the year date that is a Thursday to Sunday we need to jump to the next week to avoid going to earlier days in the prior year to fetch a Wednesday. To experiment with this behavior in the code below, change the LocalDate.now
call to new LocalDate( 2013, 1, 1 )
and vary the year.
Here is some example code using Joda-Time 2.4.
I test this code with 2013, 2014, and 2015. Those are handy years as the first day of the year is Tuesday, Wednesday, and Thursday respectively.
// Collection to store our found Wednesdays.
List<LocalDate> list = new ArrayList<>( 24 ); // Two wednesdays for each of 12 months is 24.
// Get first day of the year.
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" );
LocalDate firstOfYear = LocalDate.now( timeZone ).monthOfYear().withMinimumValue().dayOfMonth().withMinimumValue();
// Move from first day of the year to first Wednesday of that first month of year.
// Joda-Time follows ISO 8601 in defining the week to be MONDAY-SUNDAY.
LocalDate firstWedOfMonth;
if ( firstOfYear.getDayOfWeek() > DateTimeConstants.WEDNESDAY ) {
firstWedOfMonth = firstOfYear.plusWeeks( 1 ).withDayOfWeek( DateTimeConstants.WEDNESDAY ); // Jump a week forward to avoid getting dates from prior year.
} else { // Else the first of year is on the target day-of-week or later in the week.
firstWedOfMonth = firstOfYear.withDayOfWeek( DateTimeConstants.WEDNESDAY ); // Returns the same local date if already on a Wednesday.
}
// Capture first and third Wednesdays, then move on to next month, and repeat until past the end of year.
do {
int month = firstWedOfMonth.getMonthOfYear();
list.add( firstWedOfMonth );
list.add( firstWedOfMonth.plusWeeks( 2 ) ); // Get 2nd Wednesday of month.
// Move on to next month.
do {
firstWedOfMonth = firstWedOfMonth.plusWeeks( 1 );
} while ( month == firstWedOfMonth.getMonthOfYear() );
} while ( firstWedOfMonth.getYear() == firstOfYear.getYear() );
Dump to console.
System.out.println( "list: " + list );
When run.
List: [2014-01-01, 2014-01-15, 2014-02-05, 2014-02-19, 2014-03-05, 2014-03-19, 2014-04-02, 2014-04-16, 2014-05-07, 2014-05-21, 2014-06-04, 2014-06-18, 2014-07-02, 2014-07-16, 2014-08-06, 2014-08-20, 2014-09-03, 2014-09-17, 2014-10-01, 2014-10-15, 2014-11-05, 2014-11-19, 2014-12-03, 2014-12-17]