Первый день следующего месяца с java Joda-Time

Как бы вы переписали метод, приведенный ниже, который возвращает первый день следующего месяца, с пакетом org.joda.time в Joda-Time?

public static Date firstDayOfNextMonth() {
    Calendar nowCal = Calendar.getInstance();
    int month = nowCal.get(Calendar.MONTH) + 1;
    int year = nowCal.get(Calendar.YEAR);

    Calendar cal = Calendar.getInstance();
    cal.clear();
    cal.set(Calendar.YEAR, year);
    cal.set(Calendar.MONTH, month);
    cal.set(Calendar.DAY_OF_MONTH, 1);
    Date dueDate = new Date(cal.getTimeInMillis());

    return dueDate;
}

Ответ 1

   LocalDate today = new LocalDate();
   LocalDate d1 = today.plusMonths(1).withDayOfMonth(1);

Немного проще и чище, не так ли?: -)

Обновление: если вы хотите вернуть дату:

return new Date(d1.toDateTimeAtStartOfDay().getMillis());

но я настоятельно рекомендую вам не смешивать чистые типы DATE (т.е. день в календаре без информации о времени) с типами DATETIME, особенно с "физическим" типом datetime, как и отвратительный java.util.Date. Это похоже на преобразование из целых и плавающих типов, вы должны быть осторожны.

Ответ 2

Я предполагаю, что вы хотите вернуть объект Date, поэтому:

public static Date firstDayOfNextMonth() {
    MutableDateTime mdt = new MutableDateTime();
    mdt.addMonths(1);
    mdt.setDayOfMonth(1);
    mdt.setMillisOfDay(0); // if you want to make sure you're at midnight
    return mdt.toDate();
}

Ответ 3

Joda времени

Здесь я беру эту проблему, используя Joda-Time 2.3.

Неизменный

Как правило, вы должны использовать неизменные версии классов Joda-Time. Почти все методы возвращают новый экземпляр DateTime а не изменяют существующий экземпляр. Упрощает работу и обеспечивает автоматическую защиту потоков.

Start-Of-Day

Используйте новый метод withTimeAtStartOfDay() вместо того, чтобы установить время суток на ноль. Из-за летнего времени (DST) и других аномалий, в некоторые дни в некоторых часовых поясах, нет полуночи или 00:00:00 времени суток.

Конвертировать: juDate ↔ DateTime

Чтобы перевести экземпляр Joda-Time DateTime экземпляр java.util.Date, просто вызовите метод toDate. Нет необходимости в конструкторе по дате.

Идя в другую сторону, если вы hava java.util.Date и хотите Joda-Time DateTime, просто передайте Date в конструктор DateTime вместе с нужным объектом DateTimeZone.

Пример кода

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
// Usually better to specify a time zone rather than rely on default.
DateTime now = new DateTime( timeZone ); // Or, for default time zone: new DateTime()
DateTime monthFromNow = now.plusMonths(1);
DateTime firstOfNextMonth = monthFromNow.dayOfMonth().withMinimumValue();
DateTime firstMomentOfFirstOfNextMonth = firstOfNextMonth.withTimeAtStartOfDay();

Или, если вы маньяк, переместите все вместе в одной строке кода.

DateTime allInOneLine = new DateTime( DateTimeZone.forID( "Europe/Paris" ) ).plusMonths( 1 ).dayOfMonth().withMinimumValue().withTimeAtStartOfDay();

Перевести на старый java.util.Date для взаимодействия с другими классами/библиотеками.

java.util.Date date = firstMomentOfFirstOfNextMonth.toDate();

Сбросить консоль...

System.out.println( "now: " + now );
System.out.println( "monthFromNow: " + monthFromNow );
System.out.println( "firstOfNextMonth: " + firstOfNextMonth );
System.out.println( "firstMomentOfFirstOfNextMonth: " + firstMomentOfFirstOfNextMonth );
System.out.println( "allInOneLine: " + allInOneLine );
System.out.println( "date: " + date );

При запуске...

now: 2014-01-21T02:46:16.834+01:00
monthFromNow: 2014-02-21T02:46:16.834+01:00
firstOfNextMonth: 2014-02-01T02:46:16.834+01:00
firstMomentOfFirstOfNextMonth: 2014-02-01T00:00:00.000+01:00
allInOneLine: 2014-02-01T00:00:00.000+01:00
date: Fri Jan 31 15:00:00 PST 2014

java.time

Рамка java.time, встроенная в Java 8 и более поздние версии, вытесняет старые классы java.util.Date/.Calendar. Вдохновленный Joda-Time и намеревался стать его преемником.

Эти новые классы включают интерфейс TemporalAdjuster (учебник) с кучей реализаций в TemporalAdjusters (обратите внимание на множественное число s). Бывает, что у нас есть только необходимый регулятор: firstDayOfNextMonth.

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
LocalDate today = LocalDate.now ( zoneId );
LocalDate firstOfNextMonth = today.with ( TemporalAdjusters.firstDayOfNextMonth () );

Сбросьте консоль.

System.out.println ( "today: " + today + "  |  firstOfNextMonth: " + firstOfNextMonth );

сегодня: 2015-12-22 | firstOfNextMonth: 2016-01-01

Если вам нужна дата-время, а не только дата, настройте.

ZonedDateTime zdt = firstOfNextMonth.atStartOfDay( zoneId );

Если вам нужно использовать старый java.util.Date для работы со старыми классами, еще не обновленными до java.time, конвертировать из Instant извлеченного из объекта ZonedDateTime. Мгновенный момент времени на временной шкале в UTC.

java.util.Date date = java.util.Date.from( zdt.toInstant() );

О java.time

Рамка java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют неприятные старые устаревшие классы времени, такие как java.util.Date, Calendar и SimpleDateFormat.

Проект Joda-Time, теперь в режиме обслуживания, советует перейти на классы java.time.

Чтобы узнать больше, ознакомьтесь с учебным пособием Oracle. И поиск Qaru для многих примеров и объяснений. Спецификация - JSR 310.

Вы можете обменивать объекты java.time непосредственно с вашей базой данных. Используйте JDBC-драйвер, совместимый с JDBC 4.2 или новее. Нет необходимости в строках, нет необходимости в java.sql.*.

Где можно получить классы java.time?

  • Java SE 8, Java SE 9, Java SE 10 и более поздние версии
    • Встроенный.
    • Часть стандартного Java API с интегрированной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функциональных возможностей java.time включена обратно в Java 6 и 7 в ThreeTen-Backport.
  • Android
    • Более поздние версии реализаций пакетов Android классов java.time.
    • Для более ранних Android (<26), то ThreeTenABP проект адаптирует ThreeTen-Backport (упоминалось выше). См. Раздел Как использовать ThreeTenABP....

Проект ThreeTen-Extra расширяет java.time с дополнительными классами. Этот проект является доказательством возможных будущих дополнений к java.time. Здесь вы можете найти полезные классы, такие как Interval, YearWeek, YearQuarter и другие.

Ответ 4

в Joda API есть метод:

Date date = new LocalDate().plusMonths(1).dayOfMonth().withMinimumValue().toDate();

Надеюсь, что это поможет!

Ответ 5

то же, что и раньше, но также преобразован в java.util.Date

Дата firstDayOfNextMonth = (новый LocalDate(). плюсMonths (1).withDayOfMonth(1)). toDate();

Ответ 6

localDate = new LocalDate(). plusMonths (1).withDayOfMonth(1);

Ответ 7

Я не уверен, правильно ли "я", но здесь моя попытка: D.. например, просто не добавляйте +1 месяц???

public static Date firstDayOfNextMonth() {
        LocalDateTime now = LocalDateTime.now();
        int year = now.getYear();
        int month = now.getMonthValue();
        int day = now.getDayOfMonth();  

        Calendar cal = Calendar.getInstance();
        cal.clear();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month);
        cal.set(Calendar.DAY_OF_MONTH, 1);

        Date dueDate = new Date(cal.getTimeInMillis());

    return dueDate;
}