В Joda-Time установите DateTime в начало месяца
Мой API позволяет клиенту библиотеки передавать дату:
method(java.util.Date date)
Работа с Joda-Time, с этой даты я хотел бы извлечь месяц и повторить все дни, которые содержит этот месяц.
Теперь, прошедшая дата, как правило, новая Date() - значение текущего момента. Моя проблема заключается в установке нового экземпляра DateMidnight (jdkDate) в начале месяца.
Может ли кто-нибудь попробовать продемонстрировать этот прецедент с Joda-Time?
Ответы
Ответ 1
Полночь в начале первого дня текущего месяца определяется как:
// first midnight in this month
DateMidnight first = new DateMidnight().withDayOfMonth(1);
// last midnight in this month
DateMidnight last = first.plusMonths(1).minusDays(1);
Если начать с java.util.Date, используется другой конструктор DateMidnight:
// first midnight in java.util.Date month
DateMidnight first = new DateMidnight( date ).withDayOfMonth(1);
Joda Time java doc - https://www.joda.org/joda-time/apidocs/overview-summary.html
Ответ 2
Альтернативный способ (без учета DateMidnight) для получения первого дня месяца будет использовать:
DateTime firstDayOfMonth = new DateTime().dayOfMonth().withMinimumValue();
Ответ 3
Первый момент дня
Ответ от ngeek верен, но не может определить время в первый момент дня. Чтобы настроить время, добавьте вызов withTimeAtStartOfDay
.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
org.joda.time.DateTime startOfThisMonth = new org.joda.time.DateTime().dayOfMonth().withMinimumValue().withTimeAtStartOfDay();
org.joda.time.DateTime startofNextMonth = startOfThisMonth.plusMonths( 1 ).dayOfMonth().withMinimumValue().withTimeAtStartOfDay();
System.out.println( "startOfThisMonth: " + startOfThisMonth );
System.out.println( "startofNextMonth: " + startofNextMonth );
Когда бегать в Сиэтле, США...
startOfThisMonth: 2013-11-01T00:00:00.000-07:00
startofNextMonth: 2013-12-01T00:00:00.000-08:00
Обратите внимание на разницу в этих двух строках вывода консоли: -7 и -8 из-за перехода на летнее время.
Как правило, всегда следует указывать часовой пояс, а не полагаться на значение по умолчанию. Опущено здесь для простоты. Нужно добавить такую строку и передать объект часового пояса конструкторам, использованным в примере выше.
// Time Zone list: http://joda-time.sourceforge.net/timezones.html (Possibly out-dated, read note on that page)
// UTC time zone (no offset) has a constant, so no need to construct: org.joda.time.DateTimeZone.UTC
org.joda.time.DateTimeZone kolkataTimeZone = org.joda.time.DateTimeZone.forID( "Asia/Kolkata" );
java.time
Выше это правильно, но устарело. Библиотека Joda-Time теперь заменена фреймворком java.time, встроенным в Java 8 и более поздние версии.
LocalDate
представляет значение только для даты без времени суток и без часового пояса. Часовой пояс имеет решающее значение в определении даты. В любой данный момент дата варьируется в зависимости от зоны вокруг земного шара.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
Используйте один из TemporalAdjusters
чтобы получить первый месяц.
LocalDate firstOfMonth = today.with( TemporalAdjusters.firstDayOfMonth() );
LocalDate
может генерировать ZonedDateTime
который представляет первый момент дня.
ZonedDateTime firstMomentOfCurrentMonth = firstOfMonth.atStartOfDay( zoneId );
Ответ 4
О, я не видел, что это было о jodatime. В любом случае:
Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
int min = c.getActualMinimum(Calendar.DAY_OF_MONTH);
int max = c.getActualMaximum(Calendar.DAY_OF_MONTH);
for (int i = min; i <= max; i++) {
c.set(Calendar.DAY_OF_MONTH, i);
System.out.println(c.getTime());
}
Или используя commons-lang:
Date min = DateUtils.truncate(date, Calendar.MONTH);
Date max = DateUtils.addMonths(min, 1);
for (Date cur = min; cur.before(max); cur = DateUtils.addDays(cur, 1)) {
System.out.println(cur);
}
Ответ 5
DateMidnight
теперь устарел. Вместо этого вы можете:
LocalDate firstOfMonth = new LocalDate(date).withDayOfMonth(1);
LocalDate lastOfMonth = firstOfMonth.plusMonths(1).minusDays(1);
Если вы знаете, что часовой пояс использует new LocalDate(date, timeZone)
для большей точности.
Вы также можете сделать .dayOfMonth().withMinimumValue()
вместо .withDayOfMonth(1)
EDIT:
Это даст вам 12/1/YYYY 00:00
и 12/31/YYYY 00:00
. Если вы предпочтете последний месяц в качестве первого из следующего месяца (потому что вы делаете предложение inter), то удалите minusDays(1)
из вычисления lastOfMonth