jdk/src/share/classes/java/time/temporal/WeekFields.java
changeset 17474 8c100beabcc0
parent 16852 60207b2b4b42
child 19030 32f129cb6351
equal deleted inserted replaced
17473:35cd9b3a98ff 17474:8c100beabcc0
   168  * <tr><th>2009-01-04</th><td>Sunday</td>
   168  * <tr><th>2009-01-04</th><td>Sunday</td>
   169  *  <td>Week 1 of 2009</td><td>Week 53 of 2008</td></tr>
   169  *  <td>Week 1 of 2009</td><td>Week 53 of 2008</td></tr>
   170  * <tr><th>2009-01-05</th><td>Monday</td>
   170  * <tr><th>2009-01-05</th><td>Monday</td>
   171  *  <td>Week 2 of 2009</td><td>Week 1 of 2009</td></tr>
   171  *  <td>Week 2 of 2009</td><td>Week 1 of 2009</td></tr>
   172  * </table>
   172  * </table>
   173  * <h3>Specification for implementors</h3>
   173  *
       
   174  * @implSpec
   174  * This class is immutable and thread-safe.
   175  * This class is immutable and thread-safe.
   175  *
   176  *
   176  * @since 1.8
   177  * @since 1.8
   177  */
   178  */
   178 public final class WeekFields implements Serializable {
   179 public final class WeekFields implements Serializable {
   198      * up the passage of days instead of the standard year/month/day.
   199      * up the passage of days instead of the standard year/month/day.
   199      * <p>
   200      * <p>
   200      * Note that the first week may start in the previous calendar year.
   201      * Note that the first week may start in the previous calendar year.
   201      * Note also that the first few days of a calendar year may be in the
   202      * Note also that the first few days of a calendar year may be in the
   202      * week-based-year corresponding to the previous calendar year.
   203      * week-based-year corresponding to the previous calendar year.
   203      * <p>
       
   204      * This field is an immutable and thread-safe singleton.
       
   205      */
   204      */
   206     public static final WeekFields ISO = new WeekFields(DayOfWeek.MONDAY, 4);
   205     public static final WeekFields ISO = new WeekFields(DayOfWeek.MONDAY, 4);
   207 
   206 
   208     /**
   207     /**
   209      * The common definition of a week that starts on Sunday and the first week
   208      * The common definition of a week that starts on Sunday and the first week
   210      * has a minimum of 1 day.
   209      * has a minimum of 1 day.
   211      * <p>
   210      * <p>
   212      * Defined as starting on Sunday and with a minimum of 1 day in the month.
   211      * Defined as starting on Sunday and with a minimum of 1 day in the month.
   213      * This week definition is in use in the US and other European countries.
   212      * This week definition is in use in the US and other European countries.
   214      * <p>
       
   215      * This field is an immutable and thread-safe singleton.
       
   216      */
   213      */
   217     public static final WeekFields SUNDAY_START = WeekFields.of(DayOfWeek.SUNDAY, 1);
   214     public static final WeekFields SUNDAY_START = WeekFields.of(DayOfWeek.SUNDAY, 1);
   218 
   215 
   219     /**
   216     /**
   220      * The unit that represents week-based-years for the purpose of addition and subtraction.
   217      * The unit that represents week-based-years for the purpose of addition and subtraction.
   228      * for the week-based-year field retaining the week-of-week-based-year
   225      * for the week-based-year field retaining the week-of-week-based-year
   229      * and day-of-week, unless the week number it too large for the target year.
   226      * and day-of-week, unless the week number it too large for the target year.
   230      * In that case, the week is set to the last week of the year
   227      * In that case, the week is set to the last week of the year
   231      * with the same day-of-week.
   228      * with the same day-of-week.
   232      * <p>
   229      * <p>
   233      * This field is an immutable and thread-safe singleton.
   230      * This unit is an immutable and thread-safe singleton.
   234      */
   231      */
   235     public static final TemporalUnit WEEK_BASED_YEARS = IsoFields.WEEK_BASED_YEARS;
   232     public static final TemporalUnit WEEK_BASED_YEARS = IsoFields.WEEK_BASED_YEARS;
   236 
   233 
   237     /**
   234     /**
   238      * Serialization version.
   235      * Serialization version.
   245     private final DayOfWeek firstDayOfWeek;
   242     private final DayOfWeek firstDayOfWeek;
   246     /**
   243     /**
   247      * The minimal number of days in the first week.
   244      * The minimal number of days in the first week.
   248      */
   245      */
   249     private final int minimalDays;
   246     private final int minimalDays;
   250 
       
   251     /**
   247     /**
   252      * The field used to access the computed DayOfWeek.
   248      * The field used to access the computed DayOfWeek.
   253      */
   249      */
   254     private transient final TemporalField dayOfWeek = ComputedDayOfField.ofDayOfWeekField(this);
   250     private transient final TemporalField dayOfWeek = ComputedDayOfField.ofDayOfWeekField(this);
   255 
       
   256     /**
   251     /**
   257      * The field used to access the computed WeekOfMonth.
   252      * The field used to access the computed WeekOfMonth.
   258      */
   253      */
   259     private transient final TemporalField weekOfMonth = ComputedDayOfField.ofWeekOfMonthField(this);
   254     private transient final TemporalField weekOfMonth = ComputedDayOfField.ofWeekOfMonthField(this);
   260 
       
   261     /**
   255     /**
   262      * The field used to access the computed WeekOfYear.
   256      * The field used to access the computed WeekOfYear.
   263      */
   257      */
   264     private transient final TemporalField weekOfYear = ComputedDayOfField.ofWeekOfYearField(this);
   258     private transient final TemporalField weekOfYear = ComputedDayOfField.ofWeekOfYearField(this);
   265 
       
   266     /**
   259     /**
   267      * The field that represents the week-of-week-based-year.
   260      * The field that represents the week-of-week-based-year.
   268      * <p>
   261      * <p>
   269      * This field allows the week of the week-based-year value to be queried and set.
   262      * This field allows the week of the week-based-year value to be queried and set.
   270      * <p>
   263      * <p>
   271      * This unit is an immutable and thread-safe singleton.
   264      * This unit is an immutable and thread-safe singleton.
   272      */
   265      */
   273     private transient final TemporalField weekOfWeekBasedYear = ComputedDayOfField.ofWeekOfWeekBasedYearField(this);
   266     private transient final TemporalField weekOfWeekBasedYear = ComputedDayOfField.ofWeekOfWeekBasedYearField(this);
   274 
       
   275     /**
   267     /**
   276      * The field that represents the week-based-year.
   268      * The field that represents the week-based-year.
   277      * <p>
   269      * <p>
   278      * This field allows the week-based-year value to be queried and set.
   270      * This field allows the week-based-year value to be queried and set.
   279      * <p>
   271      * <p>
   280      * This unit is an immutable and thread-safe singleton.
   272      * This unit is an immutable and thread-safe singleton.
   281      */
   273      */
   282     private transient final TemporalField weekBasedYear = ComputedDayOfField.ofWeekBasedYearField(this);
   274     private transient final TemporalField weekBasedYear = ComputedDayOfField.ofWeekBasedYearField(this);
   283 
   275 
       
   276     //-----------------------------------------------------------------------
   284     /**
   277     /**
   285      * Obtains an instance of {@code WeekFields} appropriate for a locale.
   278      * Obtains an instance of {@code WeekFields} appropriate for a locale.
   286      * <p>
   279      * <p>
   287      * This will look up appropriate values from the provider of localization data.
   280      * This will look up appropriate values from the provider of localization data.
   288      *
   281      *
   357      */
   350      */
   358     private Object readResolve() throws InvalidObjectException {
   351     private Object readResolve() throws InvalidObjectException {
   359         try {
   352         try {
   360             return WeekFields.of(firstDayOfWeek, minimalDays);
   353             return WeekFields.of(firstDayOfWeek, minimalDays);
   361         } catch (IllegalArgumentException iae) {
   354         } catch (IllegalArgumentException iae) {
   362             throw new InvalidObjectException("Invalid serialized WeekFields: "
   355             throw new InvalidObjectException("Invalid serialized WeekFields: " + iae.getMessage());
   363                     + iae.getMessage());
       
   364         }
   356         }
   365     }
   357     }
   366 
   358 
   367     //-----------------------------------------------------------------------
   359     //-----------------------------------------------------------------------
   368     /**
   360     /**
   392         return minimalDays;
   384         return minimalDays;
   393     }
   385     }
   394 
   386 
   395     //-----------------------------------------------------------------------
   387     //-----------------------------------------------------------------------
   396     /**
   388     /**
   397      * Returns a field to access the day of week,
   389      * Returns a field to access the day of week based on this {@code WeekFields}.
   398      * computed based on this WeekFields.
   390      * <p>
   399      * <p>
   391      * This is similar to {@link ChronoField#DAY_OF_WEEK} but uses values for
   400      * The days of week are numbered from 1 to 7.
   392      * the day-of-week based on this {@code WeekFields}.
   401      * Day number 1 is the {@link #getFirstDayOfWeek() first day-of-week}.
   393      * The days are numbered from 1 to 7 where the
   402      *
   394      * {@link #getFirstDayOfWeek() first day-of-week} is assigned the value 1.
   403      * @return the field for day-of-week using this week definition, not null
   395      * <p>
       
   396      * For example, if the first day-of-week is Sunday, then that will have the
       
   397      * value 1, with other days ranging from Monday as 2 to Saturday as 7.
       
   398      *
       
   399      * @return a field providing access to the day-of-week with localized numbering, not null
   404      */
   400      */
   405     public TemporalField dayOfWeek() {
   401     public TemporalField dayOfWeek() {
   406         return dayOfWeek;
   402         return dayOfWeek;
   407     }
   403     }
   408 
   404 
   409     /**
   405     /**
   410      * Returns a field to access the week of month,
   406      * Returns a field to access the week of month based on this {@code WeekFields}.
   411      * computed based on this WeekFields.
       
   412      * <p>
   407      * <p>
   413      * This represents the concept of the count of weeks within the month where weeks
   408      * This represents the concept of the count of weeks within the month where weeks
   414      * start on a fixed day-of-week, such as Monday.
   409      * start on a fixed day-of-week, such as Monday.
   415      * This field is typically used with {@link WeekFields#dayOfWeek()}.
   410      * This field is typically used with {@link WeekFields#dayOfWeek()}.
   416      * <p>
   411      * <p>
   424      * - if the 2nd day of the month is a Monday, week one starts on the 2nd and the 1st is in week zero<br>
   419      * - if the 2nd day of the month is a Monday, week one starts on the 2nd and the 1st is in week zero<br>
   425      * - if the 4th day of the month is a Monday, week one starts on the 4th and the 1st to 3rd is in week zero<br>
   420      * - if the 4th day of the month is a Monday, week one starts on the 4th and the 1st to 3rd is in week zero<br>
   426      * - if the 5th day of the month is a Monday, week two starts on the 5th and the 1st to 4th is in week one<br>
   421      * - if the 5th day of the month is a Monday, week two starts on the 5th and the 1st to 4th is in week one<br>
   427      * <p>
   422      * <p>
   428      * This field can be used with any calendar system.
   423      * This field can be used with any calendar system.
   429      * @return a TemporalField to access the WeekOfMonth, not null
   424      *
       
   425      * @return a field providing access to the week-of-month, not null
   430      */
   426      */
   431     public TemporalField weekOfMonth() {
   427     public TemporalField weekOfMonth() {
   432         return weekOfMonth;
   428         return weekOfMonth;
   433     }
   429     }
   434 
   430 
   435     /**
   431     /**
   436      * Returns a field to access the week of year,
   432      * Returns a field to access the week of year based on this {@code WeekFields}.
   437      * computed based on this WeekFields.
       
   438      * <p>
   433      * <p>
   439      * This represents the concept of the count of weeks within the year where weeks
   434      * This represents the concept of the count of weeks within the year where weeks
   440      * start on a fixed day-of-week, such as Monday.
   435      * start on a fixed day-of-week, such as Monday.
   441      * This field is typically used with {@link WeekFields#dayOfWeek()}.
   436      * This field is typically used with {@link WeekFields#dayOfWeek()}.
   442      * <p>
   437      * <p>
   450      * - if the 2nd day of the year is a Monday, week one starts on the 2nd and the 1st is in week zero<br>
   445      * - if the 2nd day of the year is a Monday, week one starts on the 2nd and the 1st is in week zero<br>
   451      * - if the 4th day of the year is a Monday, week one starts on the 4th and the 1st to 3rd is in week zero<br>
   446      * - if the 4th day of the year is a Monday, week one starts on the 4th and the 1st to 3rd is in week zero<br>
   452      * - if the 5th day of the year is a Monday, week two starts on the 5th and the 1st to 4th is in week one<br>
   447      * - if the 5th day of the year is a Monday, week two starts on the 5th and the 1st to 4th is in week one<br>
   453      * <p>
   448      * <p>
   454      * This field can be used with any calendar system.
   449      * This field can be used with any calendar system.
   455      * @return a TemporalField to access the WeekOfYear, not null
   450      *
       
   451      * @return a field providing access to the week-of-year, not null
   456      */
   452      */
   457     public TemporalField weekOfYear() {
   453     public TemporalField weekOfYear() {
   458         return weekOfYear;
   454         return weekOfYear;
   459     }
   455     }
   460 
   456 
   461     /**
   457     /**
   462      * Returns a field to access the week of a week-based-year,
   458      * Returns a field to access the week of a week-based-year based on this {@code WeekFields}.
   463      * computed based on this WeekFields.
       
   464      * <p>
   459      * <p>
   465      * This represents the concept of the count of weeks within the year where weeks
   460      * This represents the concept of the count of weeks within the year where weeks
   466      * start on a fixed day-of-week, such as Monday and each week belongs to exactly one year.
   461      * start on a fixed day-of-week, such as Monday and each week belongs to exactly one year.
   467      * This field is typically used with {@link WeekFields#dayOfWeek()} and
   462      * This field is typically used with {@link WeekFields#dayOfWeek()} and
   468      * {@link WeekFields#weekBasedYear()}.
   463      * {@link WeekFields#weekBasedYear()}.
   480      *   the 1st to 3rd is in the last week of the previous year<br>
   475      *   the 1st to 3rd is in the last week of the previous year<br>
   481      * - if the 5th day of the year is a Monday, week two starts on the 5th and
   476      * - if the 5th day of the year is a Monday, week two starts on the 5th and
   482      *   the 1st to 4th is in week one<br>
   477      *   the 1st to 4th is in week one<br>
   483      * <p>
   478      * <p>
   484      * This field can be used with any calendar system.
   479      * This field can be used with any calendar system.
   485      * @return a TemporalField to access the week of week-based-year, not null
   480      *
       
   481      * @return a field providing access to the week-of-week-based-year, not null
   486      */
   482      */
   487     public TemporalField weekOfWeekBasedYear() {
   483     public TemporalField weekOfWeekBasedYear() {
   488         return weekOfWeekBasedYear;
   484         return weekOfWeekBasedYear;
   489     }
   485     }
   490 
   486 
   491     /**
   487     /**
   492      * Returns a field to access the year of a week-based-year,
   488      * Returns a field to access the year of a week-based-year based on this {@code WeekFields}.
   493      * computed based on this WeekFields.
       
   494      * <p>
   489      * <p>
   495      * This represents the concept of the year where weeks start on a fixed day-of-week,
   490      * This represents the concept of the year where weeks start on a fixed day-of-week,
   496      * such as Monday and each week belongs to exactly one year.
   491      * such as Monday and each week belongs to exactly one year.
   497      * This field is typically used with {@link WeekFields#dayOfWeek()} and
   492      * This field is typically used with {@link WeekFields#dayOfWeek()} and
   498      * {@link WeekFields#weekOfWeekBasedYear()}.
   493      * {@link WeekFields#weekOfWeekBasedYear()}.
   502      * Thus, week one may start before the start of the year.
   497      * Thus, week one may start before the start of the year.
   503      * If the first week starts after the start of the year then the period before
   498      * If the first week starts after the start of the year then the period before
   504      * is in the last week of the previous year.
   499      * is in the last week of the previous year.
   505      * <p>
   500      * <p>
   506      * This field can be used with any calendar system.
   501      * This field can be used with any calendar system.
   507      * @return a TemporalField to access the year of week-based-year, not null
   502      *
       
   503      * @return a field providing access to the week-based-year, not null
   508      */
   504      */
   509     public TemporalField weekBasedYear() {
   505     public TemporalField weekBasedYear() {
   510         return weekBasedYear;
   506         return weekBasedYear;
   511     }
   507     }
   512 
   508 
   513     /**
   509     //-----------------------------------------------------------------------
   514      * Checks if this WeekFields is equal to the specified object.
   510     /**
       
   511      * Checks if this {@code WeekFields} is equal to the specified object.
   515      * <p>
   512      * <p>
   516      * The comparison is based on the entire state of the rules, which is
   513      * The comparison is based on the entire state of the rules, which is
   517      * the first day-of-week and minimal days.
   514      * the first day-of-week and minimal days.
   518      *
   515      *
   519      * @param object  the other rules to compare to, null returns false
   516      * @param object  the other rules to compare to, null returns false
   529         }
   526         }
   530         return false;
   527         return false;
   531     }
   528     }
   532 
   529 
   533     /**
   530     /**
   534      * A hash code for these rules.
   531      * A hash code for this {@code WeekFields}.
   535      *
   532      *
   536      * @return a suitable hash code
   533      * @return a suitable hash code
   537      */
   534      */
   538     @Override
   535     @Override
   539     public int hashCode() {
   536     public int hashCode() {
   540         return firstDayOfWeek.ordinal() * 7 + minimalDays;
   537         return firstDayOfWeek.ordinal() * 7 + minimalDays;
   541     }
   538     }
   542 
   539 
   543     //-----------------------------------------------------------------------
   540     //-----------------------------------------------------------------------
   544     /**
   541     /**
   545      * A string representation of this definition.
   542      * A string representation of this {@code WeekFields} instance.
   546      *
   543      *
   547      * @return the string representation, not null
   544      * @return the string representation, not null
   548      */
   545      */
   549     @Override
   546     @Override
   550     public String toString() {
   547     public String toString() {
   955         }
   952         }
   956 
   953 
   957         /**
   954         /**
   958          * Map the field range to a week range of a week year.
   955          * Map the field range to a week range of a week year.
   959          * @param temporal  the temporal
   956          * @param temporal  the temporal
   960          * @param field  the field to get the range of
       
   961          * @return the ValueRange with the range adjusted to weeks.
   957          * @return the ValueRange with the range adjusted to weeks.
   962          */
   958          */
   963         private ValueRange rangeWeekOfWeekBasedYear(TemporalAccessor temporal) {
   959         private ValueRange rangeWeekOfWeekBasedYear(TemporalAccessor temporal) {
   964             if (!temporal.isSupported(DAY_OF_YEAR)) {
   960             if (!temporal.isSupported(DAY_OF_YEAR)) {
   965                 return WEEK_OF_YEAR_RANGE;
   961                 return WEEK_OF_YEAR_RANGE;