2009-10-28 13 views
45

Jak uzyskać następny piątek z interfejsem API Joda-Time.Czas: Jak zdobyć kolejny piątek?

Dzisiejsza LocalDate to today. Wygląda na to, że musisz zdecydować, gdzie jesteś przed lub po piątku bieżącego tygodnia. Zobacz tę metodę:

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

Czy można zrobić to krócej lub z onelinerem?

PS: Proszę nie informuj mnie o stosowaniu daty/czasu JDKs. Joda-Time to znacznie lepszy interfejs API.

Java 8 wprowadza pakiet java.time (Tutorial), który jest jeszcze lepszy.

+2

dobre pytanie ... 'DateTime' przydałoby się' rollForwardTo (...) 'metoda – skaffman

+0

@skaffman Zobacz mój rodzajowego ROLLFORWARD odpowiedź. Nie jest testowany przez super-duperów, ale wydaje się, że działa dla mnie. –

+1

W rzeczywistości java.time jest * niekoniecznie lepsze niż [Joda-Time] (http://www.joda.org/joda-time/). Każdy ma funkcje innych braków. Na przykład java.time nie ma klasy "' Interval' "(http://www.joda.org/joda-time/apidocs/org/joda/time/Interval.html) znalezionej w Joda-Time. Więc używaj ich dla swoich mocnych stron. Możesz łączyć ze sobą w ramach projektu. Po prostu zachowaj ostrożność w instrukcjach 'import', ponieważ niektóre z ich klas mają tę samą nazwę. –

Odpowiedz

39

java.time

Z java.time ramach wbudowany w Java 8 i późniejszych (Tutorial) można użyć TemporalAdjusters dostać next lub previousday-of-week.

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

Czy używa to czasu joda? –

+2

Nie, ale wyrosło z niego. Tutaj cytat ze strony głównej czasu joda: _Joda-Time jest de facto standardową biblioteką dat i czasu Java przed Java SE 8. Użytkownicy są teraz proszeni o migrację do java.time (JSR-310) ._ –

+1

FYI, [java.time] (http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) klasy są wbudowane w Javę 8 i później. Znaczna część funkcji java.time została przeniesiona do wersji Java 6 i 7 w [ThreeTen-Backport] (http://www.threeten.org/threetenbp/) i dodatkowo przystosowana do systemu Android w [ThreeTenABP] (https://github.com/JakeWharton/ThreeTenABP). Zobacz także [Samouczek Oracle] (http://docs.oracle.com/javase/tutorial/datetime/TOC.html), aby dowiedzieć się więcej. –

49

Jest możliwe, aby to zrobić w znacznie łatwiejsze do odczytania sposób:

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

lub w nieco krótsza forma

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 
} 

lub nawet krócej

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

PS. Nie testowałem rzeczywistego kodu! :)

+2

lub skompiluj go ... "DateTimeConstans" –

+8

@ David już nic nie widział;) – Esko

+5

+1 dla poczucia humoru. :) –

5

Twój kod w 1 linii

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

alternatywne podejście

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

nieco przetestowany ;-)

+1

Dzięki za odpowiedź. Twoja sugestia z bardziej ogólnym podejściem jest przyjemna. Ale oneliner jest niezręczny pod względem czytelności. –

+5

@michaelkebe poprosiłeś o oneliner, właśnie dostałem jedną ... ;-) – fvu

+1

@ michael.kebe Zwykle umieszczam newlines z ternaries na "?" i ":", format trafień w Eclipse i układa się całkiem dobrze. – gyorgyabraham

4

po prostu zmarnowany jak 30 minut próbuje dowiedzieć się tego sam, ale Musiałem generalnie posuwać się naprzód.

Zresztą tu jest moje rozwiązanie:

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

Teraz wystarczy dokonać częściowego (co LOCALDATE jest) na dzień tygodnia.

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

Teraz niezależnie od najbardziej znaczącego pola częściowego będzie +1, jeśli bieżąca data jest po nim (teraz).

Oznacza to, że jeśli dokonasz częściowej transakcji z marcem 2012 r., Zostanie utworzona nowa data z marca 2013 lub <.

3

liczenie bajtów @fvu odpowiedź może ulec skróceniu nawet dalej:

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

Parametr 0 do niedzieli 5 do piątku w przyszłym tygodniu

public java.util.Calendar getNextweekOfDay(int weekOfDay) throws Exception{ 
     java.util.Calendar today = java.util.Calendar.getInstance(); 
     int dayOfWeek = today.get(java.util.Calendar.DAY_OF_WEEK); 
     int daysUntilNextWeekOfDay = weekOfDay - dayOfWeek; 
     java.util.Calendar nextWeekOfDay = (java.util.Calendar)today.clone(); 
      nextWeekOfDay.add(java.util.Calendar.DAY_OF_WEEK, daysUntilNextWeekOfDay); 
      nextWeekOfDay.add(java.util.Calendar.DAY_OF_WEEK, 7); 
      nextWeekOfDay.set(java.util.Calendar.HOUR_OF_DAY, 0); 
     return nextWeekOfDay; 
    }