несоответствие значения месяца по сравнению с GregorianCalendar

Я работаю над существующим Java-приложением. Мое требование - передать значение месяца службе. Раньше в моем коде они использовали GregorianCalendar для представления дат. В настоящее время я изменил часть кода, чтобы использовать org.joda.time.LocalDate. Я знаю, что индекс даты в GregorianCalendar начинается с нуля, поэтому на сегодняшний день он отображается как 13.09.2016 (соответствует 09 октября). Но с моим представлением LocalDate это 13.10.2016. Как я могу изменить свой код, чтобы он соответствовал значениям существующего кода (т.е. 13.09.2016 для представления 13 октября 2016 г.).

Ниже мой код.

MyForm.java

private Date myDate;
public java.util.Date getMyDate()
{
    return this.myDate;
}
public void setDate()
{
    int day = getMyDay();
    int month = getMyMonth();
    GregorianCalendar gc = new GregorianCalendar();
    // Advance to next year if the month selected is before current month. This
    // only happens at year end.
    if (gc.get(Calendar.MONTH) > month)
    {
        gc.add(Calendar.YEAR, 1);
    }
   gc.set(Calendar.DATE, day);
    gc.set(Calendar.MONTH, month);
    this.myDate = gc.getTime();
}

MyAction.java

Ниже код представляет мою строку [], которая содержит значения даты.

    List<LocalDate> localDatesList = service.getMyDates();
    final List<String> tempDatesList = new ArrayList<>(localDatesList.size());
        for (final LocalDate date : localDatesList) {
            tempDatesList.add(date.toString());
        }
        final String[] formattedDates = tempDatesList.toArray(new String[localDatesList.size()]);
//represents the dates as 2016-10-14 2016-10-15 .

Посоветуйте, как лучше решить эту проблему. Какой из них будет лучшим вариантом для изменения. Можем ли мы обработать несоответствие этого месяца из LocalDate и GregorianCalendar, чтобы при сравнении объекты, созданные из LocalDate и GregorianCalendar, имели одинаковое значение месяца.

--EDIT-- Я хочу преобразовать List<LocalDate> ниже, чтобы он соответствовал GregorianCalendar. Я хочу, чтобы моя строка [] содержала значения, которые соответствуют значениям даты GregorianCalendar (т.е. 9 для представления месяца октябрь). Пожалуйста, посоветуйте, мне нужно преобразовать LocalDate в GregorianCalendar...

List<LocalDate> localDatesList = service.getMyDates();
final List<String> tempDatesList = new ArrayList<>(localDatesList.size());
    for (final LocalDate date : localDatesList) {
        tempDatesList.add(date.toString());
    }
    final String[] formattedDates = tempDatesList.toArray(new String[localDatesList.size()]);

person joan    schedule 13.10.2016    source источник
comment
Я не понимаю, что ты собираешься делать. Что-то вроде stackoverflow.com/questions/26246030/ ???   -  person GhostCat    schedule 13.10.2016
comment
@GhostCat - Существующий код в моем приложении использует GregorianCalendar API, и с этим индексом значения месяца начинается с 0, поэтому для октября он представляет 09 как значение месяца. Но для LocalDate значение месяца равно 10 для октября. Я хочу, чтобы значения месяца совпадали в API LocalDate и GregorianCalendar.   -  person joan    schedule 13.10.2016
comment
Любая дата GregorianCalendar, правильно отформатированная с помощью DateTimeFormatter, будет отображать 10 в числовом представлении октября. Если вы используете простой формат, вам придется добавить 1.   -  person laune    schedule 13.10.2016


Ответы (1)


Вы неправильно предполагаете

Вы неправильно понимаете класс [java.util.GregorianCalendar][1] и java.util.Calendar. При создании форматированных строк для представления значения даты и времени он, конечно, сообщает о месяцах с января по декабрь как 1-12, а 10 — как октябрь. Таким образом, 13 октября действительно будет представлено как 10/13/2016, а не 09/13/2016, как вы ошибочно утверждаете.

Проблема связана с методами получения и установки месяца, где он странным образом использует индекс с отсчетом от нуля от 0 до 11. Одна из многих причин избегать проблемных устаревших классов даты и времени. Чтобы процитировать классный документ…

java.util.Calendar.MONTH

…Первый месяц года в григорианском и юлианском календарях – ЯНВАРЬ, что равно 0; последнее зависит от количества месяцев в году.

Java.время

К вашему сведению, проект Joda-Time теперь находится в режим обслуживания, где команда рекомендует перейти на java.time.

В приведенном ниже коде используются классы java.time. Концепции аналогичны Joda-Time, поскольку Joda-Time послужил источником вдохновения для java.time.

Преобразование

Ваш вопрос довольно запутанный и запутанный.

Правильное преобразование может решить ваши проблемы. Старайтесь выполнять большую часть своей работы в классах java.time и сведите к минимуму использование старых классов Date и Calendar. Чтобы преобразовать туда и сюда, посмотрите на новые методы, добавленные к старым классам и т. д. См. мой вопрос Преобразовать java.util.Date в какой тип "java.time"? для дальнейшего обсуждения.

ZonedDateTime zdt = myGregorianCalendar.toZonedDateTime();
LocalDate ld = zdt.toLocalDate();
Month m = ld.toMonth(); // `Month` enum object, not a number.
int monthNumber = m.getValue();  // Month number 1-12 for Jan-Dec.

Или проще:

int monthNumber = myGregorianCalendar.toZonedDateTime().getMonthValue() ;

Так или иначе, вы получите вменяемое число 1-12 января-декабря.

Идем в другом направлении.

GregorianCalendar gc = java.util.GregorianCalendar.from( myZonedDateTime );

Обратите внимание, что я вообще не манипулирую полем месяца ни для объекта, ни для GregorianCalendar, ни для ZonedDateTime.

Совет: Вместо того, чтобы передавать простое целое число для представления месяца, вместо этого используйте Month enum объекты . Это делает ваш код более самодокументируемым, обеспечивает диапазон допустимых значений и обеспечивает безопасность типов.

О java.time

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

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

Чтобы узнать больше, см. учебник по Oracle. И поищите множество примеров и пояснений в Stack Overflow. Спецификация: JSR 310.

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

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Часть стандартного Java API со встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

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

person Basil Bourque    schedule 21.10.2016