Good design of a localized YearWeek according to JSR-310

133 Views Asked by At

I need an object that represents a localized concept of a seven days week. That object is pretty much the same as the YearWeek found in the ThreeTen-Extra library, except that the first day and the minimal number of days varies.

I thought initially to implement a LocalizedYearWeek, with some factory methods such as LocalizedYearWeek.of(int year, int week, WeekDefinition weekDefinition). The class WeekDefinition is merely a value object that defines the first day and the minimal number of days of a week, that can also work as a factory of WeekFields.

I'm not sure if it is the best model for such temporal, but I didn't come up with any better design ideas, so I'm looking for some guidance on how to implement it.

1

There are 1 best solutions below

3
On

tl;dr

WeekFields.of( 
    firstDayOfWeek , 
    minimumDaysInFirstWeek 
)

WeekFields

The java.time classes already support non-standard weeks. You may not need to build your own class. An implementation of java.time.Temporal with the necessary TemporalField objects has been provided in the WeekFields class.

The WeekFields.ISO constant uses standard ISO 8601 definition of a week:

  • Week # 1 holds the first Thursday of the calendar-year.
  • Week # 1 has 4 or more of its days in January
  • Week begins on Monday, ends on Sunday.

But that class is built for alternative week definitions as well. The constant WeekFields.SUNDAY_START comes configured for United States-style Sunday-Monday weeks.

DayOfWeek dow = WeekFields.SUNDAY_START.getFirstDayOfWeek() ;

dow.toString(): SUNDAY

Get the week number and week-based-year number:

LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 ) ;
int w = ld.get( WeekFields.SUNDAY_START.weekOfWeekBasedYear() ) ;
int y = ld.get( WeekFields.SUNDAY_START.weekBasedYear() ) ;

If you define a week differently, configure WeekFields as needed.

DayOfWeek firstDayOfWeek = DayOfWeek.TUESDAY ;
int minimumDaysInFirstWeek = 4 ;
WeekFields wf = WeekFields.of( firstDayOfWeek , minimumDaysInFirstWeek ) ;
int w = ld.get( wf.weekOfWeekBasedYear() ) ;
int y = ld.get( wf.weekBasedYear() ) ;

If you want to represent a year-week as a single unit, then yes, you will need to write your own class similar to org.threeten.extra.YearWeek class from ThreeTen-Extra. Such a class would contain the WeekFields object shown above, and would offer methods wrapping the code seen above. The source-code for YearWeek.java is available with a liberal license.