【问题标题】:java: represent Date with optional month and dayjava:用可选的月份和日期表示日期
【发布时间】:2020-01-29 00:39:46
【问题描述】:

我想在 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;
  }
}

【问题讨论】:

  • java.time.Yearjava.time.YearMonthjava.time.MonthDay 是否满足您的要求?
  • 你的用例是什么?一般来说,我不建议使用单个类来表示多个时间概念。 java.time 必须将其全部拆分是有原因的。
  • @Slaw 你的建议听起来不错,我可以将所有:java.time.Year、java.time.YearMonth 或 java.time.MonthDay 包装在一个类中,这样可以解决问题。跨度>
  • 请注意,已经有一个类封装了所有这些值(年、月和日):java.time.LocalDate
  • 解释您的业务问题,因为可能有比设计部分日期类更好的解决方案。

标签: java class date jodatime


【解决方案1】:

在不了解您的用例的情况下很难指导您。一种选择是使用TemporalAccessor 接口作为带有和不带有月份和/或日期的日期的常用类型,然后将LocalDateYearMonthYear 放入您的变量中(最后一个类只是称为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

我无法判断它是否或如何满足您的要求。

使用ChronoField 常量进行访问是低级的,因此您可能希望将TemporalAccessor 包装在一个带有好getter 的好类中。例如:

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 对象的构造函数和/或返回包装在 Optionals 中的那些类型的 getter。

链接: Oracle tutorial: Date Time 解释如何使用 java.time。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    相关资源
    最近更新 更多