How to find the nearest weekly day on an arbitrary date?

Is there an elegant way to find the nearest day of the week for a specific date using JodaTime? Initially, I thought it would be setCopy() , but it sets the day on the same day in the same week. So, if ld is 2011-11-27 and day is Monday, the next function returns 2011-11-21 , not 2011-11-28 , as I want.

  // Note that "day" can be _any_ day of the week, not just weekdays. LocalDate getNearestDayOfWeek(LocalDate ld, String day) { return ld.dayOfWeek().setCopy(day); } 

Required output for various inputs:

 2011-12-04, Monday => 2011-12-05 2011-12-04, Tuesday => 2011-12-06 2011-12-04, Wednesday => 2011-12-07 2011-12-04, Thursday => 2011-12-01 2011-12-04, Friday => 2011-12-02 2011-12-04, Saturday => 2011-12-03 2011-12-04, Sunday => 2011-12-04 2011-12-05, Monday => 2011-12-05 2011-12-05, Tuesday => 2011-12-06 2011-12-05, Wednesday => 2011-12-07 2011-12-05, Thursday => 2011-12-08 2011-12-05, Friday => 2011-12-02 2011-12-05, Saturday => 2011-12-03 2011-12-05, Sunday => 2011-12-04 

Below is a description of the work that I came up with to work with specific limitations in my current situation, but I would really like to get help finding a completely general solution that always works.

  LocalDate getNearestDayOfWeek(LocalDate ld, String day) { LocalDate target = ld.dayOfWeek().setCopy(day); if (ld.getDayOfWeek() > DateTimeConstants.SATURDAY) { target = target.plusWeeks(1); } return target; } 
+6
source share
4 answers

In Jodatime, such things should be done with three or four lines:

  /** Given a reference LocalDate and a day of week, eg DateTimeConstants.MONDAY Returns the nearest date with that day of week */ public static LocalDate getNearestDayOfWeek(LocalDate t0,int dow) { LocalDate t1 = t0.withDayOfWeek(dow); LocalDate t2 = t1.isBefore(t0) ? t1.plusWeeks(1) : t1.minusWeeks(1); return Math.abs(Days.daysBetween(t1, t0).getDays()) < Math.abs(Days.daysBetween(t2, t0).getDays()) ? t1 : t2; } 

Or more compact and efficient:

 public static LocalDate getNearestDayOfWeek(LocalDate t0, int dow) { LocalDate t1 = t0.withDayOfWeek(dow); if (t1.isBefore(t0.minusDays(3))) return t1.plusWeeks(1); else if (t1.isAfter(t0.plusDays(3))) return t1.minusWeeks(1); else return t1; } 

And if you want to pass the day of the week as a String:

 public static LocalDate getNearestDayOfWeek(LocalDate t0, String dow) { return getNearestDayOfWeek(t0,t0.dayOfWeek().setCopy(dow).getDayOfWeek()); } 

Example:

  // prints 2011-11-28 public static void main(String[] args) throws Exception { LocalDate today = new LocalDate(2011,11,27); int dow = DateTimeConstants.MONDAY; System.out.println(getNearestDayOfWeek(today ,dow )); } 
+5
source

Something like that. For the dayOfWeek parameter, use the constants defined in org.joda.time.DateTimeConstants:

 public LocalDate getNext(int dayOfWeek) { LocalDate today = new LocalDate(); return getNext(dateOfWeek, today); } public LocalDate getNext(int dayOfWeek, LocalDate fromDate) { int dayOffset = DateTimeConstants.DAYS_PER_WEEK - dayOfWeek + 1; LocalDate weekContainingDay = fromDate.plusDays(dayOffset); return weekContainingDay.withDayOfWeek(dayOfWeek); } 

Using:

 LocalDate nextSunday = foo.getNext(DateTimeConstants.SUNDAY); 
+2
source

Here is the approach to the problem. I am a little versed in JodaTime, but not all classes and methods. I assume that given the date, you can get the day of the week and the next or previous dates.

There are three cases.

  • dayOfTheWeek for a specific date is a weekday. Return date.
  • dayOfTheWeek - Saturday. Subtract 1 day from the day. Return the date - 1 day.
  • dayOfTheWeek - Sunday. Add 1 day to your date. Return date + one day.

If dayOfTheWeek is an enumerated type, then the case statement handles the task in a direct way.

+1
source

This finds the closest day of the week by determining the interval of the closest days of the week. Yoda defines a week starting on Monday. Therefore, if today is Tuesday and the day of the week is set to Sunday, the date will be next Sunday, not the previous one. If the first day of the week is redefined on Sunday, the date indicated on the previous Sunday. The following code is not defined by the definition of the first day of the week.

  DateTime getNearestDayOfWeek (DateTime dateTime, String day) {
   // Create an interval containing the nearest days of the week.
   DateTime begin = dateTime.minusHours (DateTimeConstants.HOURS_PER_WEEK / 2) .dayOfWeek (). RoundHalfCeilingCopy ();
   DateTime end = dateTime.plusHours (DateTimeConstants.HOURS_PER_WEEK / 2) .dayOfWeek (). RoundHalfCeilingCopy ();
   Interval interval = new Interval (begin, end);

   // Adjust nearest nearest day to be within the interval.  Doesn't depend on definition of first day of the week.
   DateTime nearest = dateTime.dayOfWeek (). SetCopy (day);
   if (interval.isAfter (nearest)) // nearest is before the interval
     return nearest.plusWeeks (1);
   else if (interval.isBefore (nearest)) // nearest is after the interval
     return nearest.minusWeeks (1);
   else 
     return nearest;
 }
+1
source

Source: https://habr.com/ru/post/902725/


All Articles