Tempo: come arrivare il prossimo venerdì?
Domanda
Come posso ottenere il prossimo venerdì con l'API Joda-Time .
Il LocalDate
di oggi è today
. Mi sembra che tu debba decidere qualunque cosa tu sia prima o dopo il venerdì della settimana in corso. Vedi questo metodo:
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);
}
}
È possibile farlo più breve o con un oneliner?
PS: Per favore, non avvisarmi di usare la data / ora di JDK. Joda-Time è un'API molto migliore.
Java 8 introduce java.time pacchetto ( Tutorial ) che è ancora meglio.
Soluzione
java.time
Con il java.time framework integrato in Java 8 e versioni successive ( Tutorial ) puoi utilizzare TemporalAdjusters
per ottenere next o precedente giorno della settimana .
private LocalDate calcNextFriday(LocalDate d) {
return d.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
}
Altri suggerimenti
È possibile farlo in un modo molto più semplice da leggere:
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));
}
o in una forma un po 'più breve
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
}
o anche più breve
private LocalDate calcNextFriday(LocalDate d) {
if (d.getDayOfWeek() >= DateTimeConstants.FRIDAY) {
d = d.plusWeeks(1);
}
return d.withDayOfWeek(DateTimeConstants.FRIDAY);
}
PS. Non ho testato il codice reale! :)
Il tuo codice in 1 riga
private LocalDate calcNextFriday3(LocalDate d) {
return d.isBefore(d.dayOfWeek().setCopy(5))?d.dayOfWeek().setCopy(5):d.plusWeeks(1).dayOfWeek().setCopy(5);
}
Approccio alternativo
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);
}
un po 'testato ;-)
Ho appena sprecato 30 minuti a cercare di capirlo da solo, ma dovevo avanzare genericamente.
Comunque qui è la mia soluzione:
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;
}
Ora devi solo creare un Partial (che LocalDate è) per il giorno della settimana.
Partial().with(DateTimeFieldType.dayOfWeek(), DateTimeConstants.FRIDAY);
Ora qualunque sia il campo più significativo del parziale sarà +1 se la data corrente è successiva (ora).
Cioè se si effettua un parziale con marzo 2012, verrà creato un nuovo datetime di marzo 2013 o < ;.
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
}
il conteggio dei byte con la risposta @fvu può essere ulteriormente abbreviato in:
private LocalDate calcNextFriday(LocalDate d) {
return d.plusWeeks(d.getDayOfWeek() < DateTimeConstants.FRIDAY ? 0 : 1).withDayOfWeek(DateTimeConstants.FRIDAY);
}
Una semplice soluzione basata su modulo che dovrebbe funzionare con la maggior parte delle precedenti versioni di java nel caso in cui non ti sia permesso aggiornare la tua versione di java a java8 o successive o utilizzare una libreria di date java standard come jodatime
Il numero di giorni da aggiungere alla tua data è dato da questa formula:
(7 + Calendar.FRIDAY - yourDateAsCalendar.get (Calendar.DAY_OF_WEEK))% 7
Nota anche che questo può essere generalizzato per qualsiasi giorno della settimana cambiando il campo statico Calendar.FRIDAY nel tuo giorno della settimana specificato. Alcuni frammenti di codice di seguito
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()));
}
}