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; |