Reputation:
I would like to store Date with optional month and day in java.
I know of the java.time.LocalYear
class to store just the year.
Shall I create my own custom class to hold dates with optional month and day or are there any custom library to solve the problem.
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;
}
}
Upvotes: 0
Views: 973
Reputation: 86324
It’s hard to guide you without knowing your use case. One option is using the TemporalAccessor
interface as a common type for dates with and without month and/or day of month and then put either a LocalDate
, a YearMonth
or a Year
into your variable (the last class is just called Year
(not LocalYear
, though it would have been in line with the naming scheme)). For example:
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
What can we use this for? One example:
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();
}
This outputs:
2019-10-03 Year: 2019 Month: 10 Day: 3 2019-11 Year: 2019 Month: 11 Day: undefined 2020 Year: 2020 Month: undefined Day: undefined
Whether or how well it fulfils your requirements I cannot tell.
Using ChronoField
constants for access is low-level, so you may want to wrap the TemporalAccessor
in a nice class with nice getters. For example:
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
}
You may extend the class to your needs. Maybe you want constructors that accept a Month
enum constant and/or a YearMonth
object directly and/or getters that return those types wrapped in Optional
s.
Link: Oracle tutorial: Date Time explaining how to use java.time.
Upvotes: 3