2011-11-30 40 views
6

Có cách nào thanh lịch để tìm ngày gần nhất trong tuần cho một ngày nhất định bằng JodaTime không? Ban đầu tôi nghĩ setCopy() sẽ là nó, nhưng điều này đặt ra ngày này sang ngày đặc biệt trong cùng một tuần. Vì vậy, nếu ld2011-11-27day là "Monday" chức năng sau trả 2011-11-21, và không 2011-11-28 như tôi muốn.Làm thế nào để tìm ngày trong tuần gần nhất cho một ngày tùy ý?

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

đầu ra mong muốn cho các đầu vào khác nhau:

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 

Dưới đây là một công việc xung quanh tôi đã đưa ra mà làm việc cho những hạn chế đặc biệt trong tình hình hiện tại của tôi, nhưng tôi rất muốn được giúp đỡ tìm một giải pháp hoàn toàn chung chung luôn hoạt động.

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

thể trùng lặp của [Joda Thời gian: Làm thế nào để có được những thứ sáu tiếp theo] (http://stackoverflow.com/questions/1636038/joda-time- làm thế nào để có được-the-the-the-thứ-thứ sáu) –

+2

Tôi không nghĩ như vậy. Điều đó tìm thấy ngày _next_, nhưng tôi muốn tìm ngày _nearest_. –

+0

Bạn cần xác định ý bạn là "gần nhất" và "ngày trong tuần" để có thể cung cấp câu trả lời đúng. Có lẽ một bảng đầu vào dự kiến ​​sẽ xuất ra? – JodaStephen

Trả lời

5

Trong Jodatime, loại điều nên được doable với ba hoặc bốn dòng:

/** 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; 
    } 

Hoặc nhỏ gọn hơn và hiệu quả:

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; 
} 

Và nếu bạn muốn vượt qua ngày-trong-tuần như Chuỗi:

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

Ví dụ:

// 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)); 
    } 
+0

Điều này là tốt. Chuỗi có ý nghĩa trong tình huống cụ thể của tôi. (Tôi đã được giao dịch với tên của chuỗi ngày từ một tập tin cấu hình.) Tôi đồng ý rằng nó không phải là tốt nhất trong trường hợp chung. –

1

Đây là phương pháp tiếp cận vấn đề. Tôi biết một chút về JodaTime, nhưng không phải tất cả các lớp và phương pháp. Tôi giả định rằng một ngày, bạn có thể nhận được ngày trong tuần và ngày tiếp theo hoặc trước đó.

Có ba trường hợp.

  1. ngàyOfTheWeek cho một ngày cụ thể là ngày trong tuần. Ngày trở lại.
  2. Các dayOfTheWeek là thứ bảy. Trừ 1 ngày kể từ ngày của bạn. Trả lại ngày - 1 ngày.
  3. Các dayOfTheWeek là chủ nhật. Thêm 1 ngày vào ngày của bạn. Trả lại ngày + một ngày.

Nếu ngàyOfTheWeek là loại được liệt kê, sau đó tuyên bố trường hợp sẽ xử lý tác vụ theo cách thẳng.

+0

Tôi nghĩ rằng bạn hiểu lầm câu hỏi của tôi. Thuật toán của bạn dường như tìm thấy các ngày trong tuần gần nhất, đó không phải là những gì tôi muốn. Thay vào đó, cho bất kỳ ngày nào tôi muốn có thể hỏi "Thứ Hai gần nhất là gì? Thứ Ba? Thứ Bảy?" Tôi đã chỉnh sửa câu hỏi của mình để làm rõ điều này. –

+0

@ stig-brautaset: Vâng, tôi đã làm. Tôi nghĩ rằng tôi có thể có khi tôi đã viết câu trả lời, nhưng figured một câu trả lời sai có thể giúp có được một quyền :-) Tôi sẽ thử lại sau. –

1

Điều này tìm ngày gần nhất trong tuần bằng cách xác định khoảng thời gian các ngày gần nhất trong tuần. Joda định nghĩa một tuần bắt đầu từ thứ Hai. Vì vậy, nếu hôm nay là thứ ba và ngày trong tuần được thiết lập để chủ nhật, ngày sẽ được cho ngày chủ nhật tiếp theo, không phải là trước đó. Nếu ngày đầu tiên của tuần được xác định lại là Chủ Nhật, ngày trở về sẽ là ngày chủ nhật trước đó. Mã sau không bị ảnh hưởng bởi định nghĩa ngày đầu tiên của tuần.

 
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 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; 
} 
+0

Một cách thay thế thú vị để đi về nó. –

2

Điều gì đó tương tự. Đối với tham số dayOfWeek, sử dụng các hằng số được định nghĩa trong 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); 
} 

Cách sử dụng:

LocalDate nextSunday = foo.getNext(DateTimeConstants.SUNDAY); 
Các vấn đề liên quan