Apache DateUtils усекать день месяца
Я хотел бы создать класс DateHelper и для этого я использую DateUtils из Apache Commons Lang 2.6. У меня проблемы с пониманием результата, возвращаемого при извлечении поля из даты. Вот мой тестовый класс, который извлекает день месяца после усечения даты:
public class DateTest {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// Date date = createDate(2000, 1, 2, 3, 4, 5, 6);
Calendar calendar = createEmptyUTCCalendar();
calendar.set(Calendar.YEAR, 2000);
calendar.set(Calendar.MONTH, 0); // january
calendar.set(Calendar.DAY_OF_MONTH, 2);
calendar.set(Calendar.HOUR_OF_DAY, 3);
calendar.set(Calendar.MINUTE, 4);
calendar.set(Calendar.SECOND, 5);
calendar.set(Calendar.MILLISECOND, 6);
Date date = calendar.getTime();
System.out.println("Input date\n" + date);
// Truncate from day of month.
Date dateTruncate = getDatePart(date);
System.out.println("Truncate the date\n" + dateTruncate);
System.out.println("\n*** Extract day of month ***");
// Extract the field day of month from the truncated date.
int fieldDayOfMonth = getField(dateTruncate, Calendar.DAY_OF_MONTH);
System.out.println("Expected result is 2\nActual result is " + fieldDayOfMonth);
assert fieldDayOfMonth == 2;
}
public static int getField(Date date, int calendarField) {
Calendar calendar = createEmptyUTCCalendar();
calendar.setTime(date);
int value = calendar.get(calendarField);
if (calendarField == Calendar.MONTH) {
value++;
}
return value;
}
public static Date getDatePart(Date date) {
return DateUtils.truncate(date, Calendar.DAY_OF_MONTH);
}
private static Calendar createEmptyUTCCalendar() {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
return calendar;
}
}
Я ожидаю, что результатом извлечения поля Calendar.DAY_OF_MONTH будет 2, но я получил 1.
Input date
Sun Jan 02 04:04:05 CET 2000
Truncate the date
Sun Jan 02 00:00:00 CET 2000
*** Extract day of month ***
Expected result is 2
Actual result is 1
2 ответа
ТЛ; др
LocalDate.of( 2000 , Month.JANUARY , 2 )
.getDayOfMonth()
2
java.time
Вы можете просто использовать Java сейчас, нет необходимости в Apache DateUtils. И усечение - неправильный способ думать об этом; просто допросить за день месяц собственности.
Укажите свою дату, используя LocalDate
учебный класс. Обратите внимание на то, что java.time использует нумерацию разумных месяцев, 1-12 для января по декабрь
LocalDate ld = LocalDate.of( 2000 , 1 , 2 ) ; // January 2, 2000.
Или используйте Month
ENUM.
LocalDate ld = LocalDate.of( 2000 , Month.JANUARY , 2 ) ; // January 2, 2000.
2000-01-02
Допросить за день месяца. Ты можешь позвонить getDayOfMonth
на LocalDate
, OffsetDateTime
, а также ZonedDateTime
,
int dayOfMonth = ld.getDayOfMonth() ;
2
При получении Calendar
объект, это, вероятно, GregorianCalendar
, Если это так, вы можете легко преобразовать в классы java.time.
if( myCalendar instanceOf GregorianCalendar ) {
GregorianCalendar gc = ( GregorianCalendar ) myCalendar ; // Cast.
ZonedDateTime zdt = gc.toZonedDateTime() ; // Convert from legacy class to modern class.
int dayOfMonth = zdt.getDayOfMonth() ;
}
О java.time
Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые классы даты и времени, такие как java.util.Date
, Calendar
& SimpleDateFormat
,
Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.
Чтобы узнать больше, смотрите Oracle Tutorial. И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310.
Где взять классы java.time?
- Java SE 8, Java SE 9 и более поздние
- Встроенный.
- Часть стандартного Java API со встроенной реализацией.
- Java 9 добавляет некоторые незначительные функции и исправления.
- Java SE 6 и Java SE 7
- Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport.
- Android
- Проект ThreeTenABP адаптирует ThreeTen-Backport (упомянутый выше) специально для Android.
- Смотрите Как использовать ThreeTenABP….
Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь, такие как Interval
, YearWeek
, YearQuarter
и многое другое.
Кажется, дело в часовых поясах. Ваш календарь на UTC и ваша дата в вашей локальной зоне, если вы избегаете линии:
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
вещь должна работать.
Когда вы передаете календарь в Date, объект date получает часовой пояс CET по умолчанию в вашем случае. Затем вы усекаете и снова переходите к календарю UTC, и из-за разницы между CET и UTC ваш день является предыдущим.