Время: Как попасть в следующую пятницу?

Как получить следующую пятницу с помощью Joda-Time 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);
    }
}

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

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

В Java 8 представлен пакет java.time. (Учебник), что даже лучше.


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


Ответы (8)


Java.время

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

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

Можно сделать это гораздо проще для чтения:

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

ПС. Я не тестировал реальный код! :)

person Esko    schedule 28.10.2009
comment
или скомпилировать его... DateTimeConstans - person David Victor; 14.09.2011
comment
Строка возврата вашего последнего фрагмента содержит избыточный символ ). В любом случае, спасибо, отличное решение! - person gyorgyabraham; 16.08.2013

Ваш код в 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);
}

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

person fvu    schedule 28.10.2009
comment
Спасибо за Ваш ответ. Ваше предложение с более общим подходом приятно. Но oneliner неудобен с точки зрения удобочитаемости. - person michael.kebe; 28.10.2009
comment
@michaelkebe, вы просили написать комментарий, я только что предоставил его ... ;-) - person fvu; 28.10.2009
comment
@ michael.kebe Я обычно помещаю новые строки с тройками в ? и :, hit format в Eclipse, и это очень хорошо устраивает. - person gyorgyabraham; 16.08.2013

Я просто потратил около 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;
}

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

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

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

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

person Adam Gent    schedule 18.07.2012

подсчет байтов Ответ @fvu можно еще сократить до:

private LocalDate calcNextFriday(LocalDate d) {
  return d.plusWeeks(d.getDayOfWeek() < DateTimeConstants.FRIDAY ? 0 : 1).withDayOfWeek(DateTimeConstants.FRIDAY);
}
person Stefan Haberl    schedule 06.10.2014

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

Вот альтернативный способ сделать это без использования каких-либо других классов/API за пределами LocalDate.

     LocalDate nextFriday = (d.plusWeeks(1).withDayOfWeek(5).minusDays(7).isAfter(d)) 
                            ? d.plusWeeks(1).withDayOfWeek(5)
                            : d.withDayOfWeek(5);
person Nestor Milyaev    schedule 08.03.2021
comment
Чем это лучше принятого ответа? Я думаю, что это правильно, но мне очень трудно себя убедить. - person Ole V.V.; 08.03.2021
comment
никто не говорит, что это лучше, просто альтернативный способ сделать то же самое. Я считаю, что мой ответ имеет четкую логику и не требует знания/использования различных API/классов, отличных от LocalDate. - person Nestor Milyaev; 08.03.2021

person    schedule
comment
К вашему сведению, ужасно неприятные старые классы даты и времени, такие как java.util.Date, java.util.Calendar, и java.text.SimpleDateFormat теперь являются устаревшими и заменены java.time, встроенные в Java 8 и более поздние версии . См. учебник от Oracle. - person Basil Bourque; 30.11.2018