Вопрос по date, jodatime, time, datetime, java – Время: Как получить следующую пятницу?

51

Как я могу получить в следующую пятницу сJoda времени API.

LocalDate сегодняtoday, Мне кажется, вы должны решить, где вы находитесь до или после пятницы текущей недели. Смотрите этот метод:

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

Можно ли сделать это короче или с помощью подводки?

PS: Пожалуйста, не советуйте мне использовать дату / время JDK. Joda-Time - намного лучший API.

Java 8 вводитjava.time пакет (Руководство) что еще лучше.

хороший вопрос...DateTime мог бы использоватьrollForwardTo(...) метод skaffman
@skaffman Посмотрите мой общий ответ. Это не супер пупер проверено, но, кажется, работает для меня. Adam Gent
На самом деле, java.timeне обязательно лучшеJoda времени, У каждого есть особенности, а у другого нет. Например, java.time не хватаетInterval класс найден в Joda-Time. Так что используйте каждый для его сильных сторон. Вы можете смешивать и сочетать в рамках проекта. Просто будьте осторожны с вашимimport заявления, как некоторые из их классов имеют одно и то же имя. Basil Bourque

Ваш Ответ

7   ответов
58
java.time

Сjava.time фреймворк, встроенный в Java 8 и позже (Руководство) вы можете использоватьTemporalAdjusters получитьследующий или жепредыдущий день недели.

private LocalDate calcNextFriday(LocalDate d) {
  return d.with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
}
Использует ли это время йода? Christopher Francisco
К вашему сведению,java.time классы встроены в Java 8 и позже. Большая часть функциональности java.time была перенесена в Java 6 & 7 вThreeTen-Backport и далее адаптирован под Android вThreeTenABP, Также смOracle Tutorial Узнать больше. Basil Bourque
Нет, но это развилось из этого. Вот цитата с домашней страницы Joda Time:Joda-Time является де-факто стандартной библиотекой даты и времени для Java до Java SE 8. Теперь пользователям предлагается перейти на java.time (JSR-310). michael.kebe
4

как 30 минут, пытаясь выяснить это сам, но мне нужно было сделать общий поворот.

В любом случае вот мое решение:

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

Теперь вам просто нужно сделать частичное (то есть LocalDate) для дня недели.

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

Теперь, какое бы ни было наиболее значимое поле частичного, будет +1, если текущая дата будет после него (сейчас).

То есть, если вы сделаете частичное с марта 2012 года, оно создаст новую дату и время марта 2013 года или <.

0

которое должно работать с большинством предыдущих версий Java, если вам не разрешено обновлять версию Java до версии java8 или более поздней или использовать стандартную библиотеку дат Java в качестве jodatime.

Количество дней, добавляемых к вашей дате, определяется по формуле:

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

Обратите внимание, что это можно обобщить для любого дня недели, изменив статическое поле Calendar.FRIDAY на заданный вами день недели. Некоторый фрагмент кода ниже

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()));
    }
}
Да, если вы используете Java 8 или более позднюю версию или Jodatime, это не для вас. Я сказал это, но мне было не ясно. Спасибо за комментарий. Breton F.
К вашему сведению, ужасно хлопотные старые классы даты и времени, такие какjava.util.Date, java.util.Calendar, а такжеjava.text.SimpleDateFormat есть сейчаснаследиевытесненыjava.time классы, встроенные в Java 8 и позже. ВидетьРуководство Oracle. Basil Bourque
3

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

Ваш код в 1 строку

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

Альтернативный подход

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

несколько проверено ;-)

@michaelkebe ты просил однодневку, я только что предоставил ... ;-) fvu
Спасибо за Ваш ответ. Ваше предложение с более общим подходом приятно. Но он неуклюжий в плане читабельности. michael.kebe
@ michael.kebe Я обычно помещаю новые строки с тройными буквами в "?" и ":", ударил формат в Eclipse, и он довольно хорошо организован. gyorgyabraham
52

Это можно сделать гораздо проще:

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

или в несколько более короткой форме

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
}

или даже короче

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

PS. Я не проверял реальный код! :)

+1 за чувство юмора. :) David Victor
@ Давид Ты ничего не видел;) Esko
или скомпилируйте его ... "DateTimeConstans" David Victor
Строка «возврата» вашего последнего фрагмента содержит избыточный символ «)». В любом случае, спасибо, отличное решение! gyorgyabraham
4
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
}
К вашему сведению, ужасно хлопотные старые классы даты и времени, такие какjava.util.Date, java.util.Calendar, а такжеjava.text.SimpleDateFormat есть сейчаснаследиевытесненыjava.time классы, встроенные в Java 8 и позже. ВидетьРуководство Oracle. Basil Bourque

Похожие вопросы