Time: How to get the next friday?

JavaDateDatetimeTimeJodatime

Java Problem Overview


How can I get the next friday with the Joda-Time API.

The LocalDate of today is today. It looks to me you have to decide whever you are before or after the friday of the current week. See this method:

private LocalDate calcNextFriday(LocalDate d) {
	LocalDate friday = d.dayOfWeek().setCopy(5);
	if (d.isBefore(friday)) {
		return d.dayOfWeek().setCopy(5);
	} else {
		return d.plusWeeks(1).dayOfWeek().setCopy(5);
	}
}

Is it possible to do it shorter or with a oneliner?

PS: Please don't advise me using JDKs date/time stuff. Joda-Time is a much better API.

Java 8 introduces java.time package (Tutorial) which is even better.

Java Solutions


Solution 1 - Java

java.time

With the java.time framework built into Java 8 and later (Tutorial) you can use TemporalAdjusters to get next or previous day-of-week.

private LocalDate calcNextFriday(LocalDate d) {
  return d.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
}

Solution 2 - Java

It's possible to do it in a much easier to read way:

if (d.getDayOfWeek() < DateTimeConstants.FRIDAY) {
    return d.withDayOfWeek(DateTimeConstants.FRIDAY));
} else if (d.getDayOfWeek() == DateTimeConstants.FRIDAY) {
    // almost useless branch, could be merged with the one above
    return d;
} else {
    return d.plusWeeks(1).withDayOfWeek(DateTimeConstants.FRIDAY));
}

or in a bit shorter form

private LocalDate calcNextFriday(LocalDate d) {    
	if (d.getDayOfWeek() < DateTimeConstants.FRIDAY) {
		d = d.withDayOfWeek(DateTimeConstants.FRIDAY));
	} else {
		d = d.plusWeeks(1).withDayOfWeek(DateTimeConstants.FRIDAY));
	}    
	return d; // note that there's a possibility original object is returned
}

or even shorter

private LocalDate calcNextFriday(LocalDate d) {
	if (d.getDayOfWeek() >= DateTimeConstants.FRIDAY) {
		d = d.plusWeeks(1);
	}
	return d.withDayOfWeek(DateTimeConstants.FRIDAY);
}

PS. I didn't test the actual code! :)

Solution 3 - Java

Your code in 1 line

private LocalDate calcNextFriday3(LocalDate d) {
    return d.isBefore(d.dayOfWeek().setCopy(5))?d.dayOfWeek().setCopy(5):d.plusWeeks(1).dayOfWeek().setCopy(5);
}

Alternative approach

private LocalDate calcNextDay(LocalDate d, int weekday) {
    return (d.getDayOfWeek() < weekday)?d.withDayOfWeek(weekday):d.plusWeeks(1).withDayOfWeek(weekday);
}


private LocalDate calcNextFriday2(LocalDate d) {
    return calcNextDay(d,DateTimeConstants.FRIDAY);
}

somewhat tested ;-)

Solution 4 - Java

I just wasted like 30 minutes trying to figure this out myself but I needed to generically roll forward.

Anyway here is my solution:

public static DateTime rollForwardWith(ReadableInstant now, AbstractPartial lp) {
    DateTime dt = lp.toDateTime(now);
    while (dt.isBefore(now)) {
        dt = dt.withFieldAdded(lp.getFieldTypes()[0].getRangeDurationType(), 1);
    }
    return dt;
}

Now you just need to make a Partial (which LocalDate is) for the day of the week.

Partial().with(DateTimeFieldType.dayOfWeek(), DateTimeConstants.FRIDAY); 

Now whatever the most significant field is of the partial will be +1 if the current date is after it (now).

That is if you make a partial with March 2012 it will create a new datetime of March 2013 or <.

Solution 5 - Java

import java.util.Calendar;

private Calendar getNextweekOfDay(int weekOfDay) {
    Calendar today = Calendar.getInstance();
    int dayOfWeek = today.get(Calendar.DAY_OF_WEEK);
    int daysUntilNextWeekOfDay = weekOfDay - dayOfWeek;
    if (daysUntilNextWeekOfDay == 0) daysUntilNextWeekOfDay = 7;
    Calendar nextWeekOfDay = (Calendar)today.clone();
    nextWeekOfDay.add(Calendar.DAY_OF_WEEK, daysUntilNextWeekOfDay);
    return nextWeekOfDay;
}

// set alarm for next Friday 9am
public void setAlarm() {
    Calendar calAlarm = getNextweekOfDay(Calendar.FRIDAY);
    calAlarm.set(Calendar.HOUR_OF_DAY, 9);//9am
    calAlarm.set(Calendar.MINUTE, 0);
    calAlarm.set(Calendar.SECOND, 0);
    scheduleAlarm(calAlarm);// this is my own method to schedule a pendingIntent
}

Solution 6 - Java

counting bytes @fvu answer can be shortened even further to:

private LocalDate calcNextFriday(LocalDate d) {
  return d.plusWeeks(d.getDayOfWeek() < DateTimeConstants.FRIDAY ? 0 : 1).withDayOfWeek(DateTimeConstants.FRIDAY);
}

Solution 7 - Java

A simple modulo based solution which should work with most of former java versions in case you are not allowed to upgrade your java version to java8 or onwards or to use a standard java date library as jodatime

Number of days to add to your date is given by this formula :

(7 + Calendar.FRIDAY - yourDateAsCalendar.get(Calendar.DAY_OF_WEEK)) % 7

Note also this can be generalized for any week day by changing the static field Calendar.FRIDAY to your given weekday. Some snippet code below

public static void main(String[] args) {
	for (int i = 0; i < 15; i++) {
		
		Calendar cur = Calendar.getInstance();
		cur.add(Calendar.DAY_OF_MONTH, i);
		
		Calendar friday = Calendar.getInstance();
		friday.setTime(cur.getTime());
		friday.add(Calendar.DAY_OF_MONTH, (7 + Calendar.FRIDAY - cur.get(Calendar.DAY_OF_WEEK)) % 7);
		
		System.out.println(MessageFormat.format("Date {0} -> {1} ", cur.getTime(),  friday.getTime()));
	}
}

Solution 8 - Java

Here's an alternative way of doing it, without using any other classes/APIs outside LocalDate.

     LocalDate nextFriday = (d.plusWeeks(1).withDayOfWeek(5).minusDays(7).isAfter(d)) 
                            ? d.plusWeeks(1).withDayOfWeek(5)
                            : d.withDayOfWeek(5);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionmichael.kebeView Question on Stackoverflow
Solution 1 - Javamichael.kebeView Answer on Stackoverflow
Solution 2 - JavaEskoView Answer on Stackoverflow
Solution 3 - JavafvuView Answer on Stackoverflow
Solution 4 - JavaAdam GentView Answer on Stackoverflow
Solution 5 - Javadinesh pazaniView Answer on Stackoverflow
Solution 6 - JavaStefan HaberlView Answer on Stackoverflow
Solution 7 - JavaBreton F.View Answer on Stackoverflow
Solution 8 - JavaNestor MilyaevView Answer on Stackoverflow