Java: представляют дату с необязательным месяцем и днем - PullRequest
0 голосов
/ 29 сентября 2019

Я хотел бы хранить дату с дополнительным месяцем и днем ​​в Java.Я знаю о java.time.LocalYear, чтобы хранить только год.Должен ли я создать свой собственный класс для хранения дат с необязательным месяцем и днем ​​или есть какая-либо пользовательская библиотека для решения проблемы.


public class Date {

  private LocalYear year;
  private int month;
  private int day;

  public Date(LocalYear year) {
   this.year = year;
  } 

  public Date(LocalYear year, int month) {
   this.year = year;
   this.month = month;
  }

  public Date(LocalYear year, int month, iny day) {
   this.year = year;
   this.month = month;
   this.day = day;
  }
}

1 Ответ

2 голосов
/ 29 сентября 2019

Сложно вести вас, не зная вашего варианта использования.Один из вариантов заключается в использовании интерфейса TemporalAccessor в качестве общего типа для дат с месяцем и без него и / или дня месяца, а затем вставьте LocalDate, YearMonth или Year в переменную (последний класспросто называется Year (не LocalYear, хотя это соответствовало бы схеме именования)).Например:

    List<TemporalAccessor> dates = List.of(
            LocalDate.of(2019, Month.OCTOBER, 3), // full date
            YearMonth.of(2019, Month.NOVEMBER), // no day of month
            Year.of(2020)); // no month or day of month

Для чего мы можем использовать это?Один пример:

    for (TemporalAccessor ta : dates) {
        System.out.println(ta);
        System.out.println("Year: " + ta.get(ChronoField.YEAR));
        if (ta.isSupported(ChronoField.MONTH_OF_YEAR)) {
            System.out.println("Month: " + ta.get(ChronoField.MONTH_OF_YEAR));
        } else {
            System.out.println("Month: undefined");
        }
        if (ta.isSupported(ChronoField.DAY_OF_MONTH)) {
            System.out.println("Day: " + ta.get(ChronoField.DAY_OF_MONTH));
        } else {
            System.out.println("Day: undefined");
        }
        System.out.println();
    }

Это выводит:

2019-10-03
Year: 2019
Month: 10
Day: 3

2019-11
Year: 2019
Month: 11
Day: undefined

2020
Year: 2020
Month: undefined
Day: undefined

Не знаю, насколько он соответствует вашим требованиям.

Использование *Константы 1020 * для доступа являются низкоуровневыми, поэтому вы можете обернуть TemporalAccessor в хороший класс с хорошими получателями.Например:

public class PartialDate {

    private TemporalAccessor date;

    public PartialDate(Year year) {
        date = year;
    }

    public PartialDate(Year year, int month) {
        date = year.atMonth(month);
    }

    public PartialDate(Year year, int month, int day) {
        date = year.atMonth(month).atDay(day);
    }

    public Year getYear() {
        return Year.from(date);
    }

    public OptionalInt getMonthValue() {
        if (date.isSupported(ChronoField.MONTH_OF_YEAR)) {
            return OptionalInt.of(date.get(ChronoField.MONTH_OF_YEAR));
        } else {
            return OptionalInt.empty();
        }
    }

    // A similar getDay method

}

Вы можете расширить класс в соответствии со своими потребностями.Может быть, вам нужны конструкторы, которые принимают константу перечисления Month и / или объект YearMonth напрямую, и / или получатели, которые возвращают эти типы, заключенные в Optional s.

Ссылка: Руководство по Oracle: Дата и время , объясняющее, как использовать java.time.

...