7

I have a javafx.scene.control.DatePicker. I want to extract the (Locale) week number from the selected date. Until now i haven't found a solution and i prefer not to write my own algorithm. I use Java8 and hope it is possible in the new java time library.

Hans
  • 523
  • 1
  • 5
  • 16
  • @Magnilex can't help much - the value returned by DatePicker is of type LocalDate ;-) To OP: can't remember whether the week # is already implemented correctly, there's a field aligned-week-of-year which might not be what you are after – kleopatra Sep 18 '14 at 13:18
  • Ok. Seems to me a convenient implementation in the java time api – Hans Sep 18 '14 at 13:42

4 Answers4

17

The Java-8-solution can take into account the local definition of a week using the value of a date-picker:

LocalDate date = datePicker.getValue(); // input from your date picker
Locale locale = Locale.US;
int weekOfYear = date.get(WeekFields.of(locale).weekOfWeekBasedYear());

Also keep in mind that the popular alternative Joda-Time does not support such a localized week-of-year fields. For example: In ISO-8601 (widely used) the week starts with Monday, in US with Sunday. Also the item when the first week of year starts in a given calendar year is dependent on the locale.

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126
9

You can use http://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html#get-java.time.temporal.TemporalField-

LocalDate localDate = LocalDate.of(2014, 9, 18); // assuming we picked 18 September 2014
int weekNumber = localDate.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);

This will give you the week number based on ISO convention.

For a locale based evaluation :

LocalDate localDate = LocalDate.of(2014, 9, 18); // assuming we picked 18 September 2014
WeekFields weekFields = WeekFields.of(Locale.US);
int weekNumber = localDate.get(weekFields.weekOfWeekBasedYear());
bowmore
  • 10,842
  • 1
  • 35
  • 43
  • Why no to use `WeekFields.SUNDAY_START`? – Alex78191 May 23 '17 at 13:25
  • @Alex78191 simply because the OP requested code for locale specific week behavior. (my example hard codes for Locale.US, but would work for any locale passed) – bowmore May 23 '17 at 13:35
  • Why you are using `IsoFields` instead of `WeekFields.ISO`? – Alex78191 May 23 '17 at 14:37
  • @Alex78191 No specific reason, both work, I guess in a system that only uses ISO, it's easier to work with IsoFields, in a system that can work with locale and ISO interchangeably WeekFields is probably the more convenient choice. – bowmore May 23 '17 at 15:51
  • @Alex78191 I was wondering, too, and found this: https://stackoverflow.com/a/23031415/3639856, i.e. IsoFields only works with ISO calendars, so imo WeekField.ISO is more generally usable, perhaps at a small performance expense. – Remigius Stalder Mar 31 '22 at 09:57
3

FX DatePicker is based on the new (to jdk8) Date/Time api - time to learn how-to use it (not entirely sure I found the shortest way, though - corrections welcome :-)

The picker's value is a LocalDate, which can be queried for certain TemporalFields. Locale-aware week-related fields are provided by the WeekFields class, f.i. weekOfYear:

DatePicker picker = new DatePicker();
picker.valueProperty().addListener((p, oldValue, newValue) -> {
    if (newValue == null) return;
    WeekFields fields = WeekFields.of(Locale.getDefault());

    // # may range from 0 ... 54 without overlapping the boundaries of calendar year
    int week = newValue.get(fields.weekOfYear());

    // # may range from 1 ... 53 with overlapping 
    int weekBased = newValue.get(fields.weekOfWeekBasedYear());

    LOG.info("week/Based " + week + "/" + weekBased);
});

To see the difference, choose f.i. January 2012 (in locales that start a week at Monday). Which one to actually use, depends on context - the picker itself uses weekOfYear (if showWeekNumbers is enabled)

Meno Hochschild
  • 42,708
  • 7
  • 104
  • 126
kleopatra
  • 51,061
  • 28
  • 99
  • 211
  • 1
    Just one small correction: `weekOfYear()` has the range **0-54** meaning that weeks are counted here bound to the normal calendar year. Weeks not belonging to that year according to the week definition in given locale are then displayed as 0 or 54. The other field `weekOfWeekBasedYear()` has the range 1-53 (in many countries like defined in ISO-8601). I admit that the names are somehow confusing as they don't follow the standard language use - also not following the terms used in ISO-paper, but are technically motivated. – Meno Hochschild Sep 19 '14 at 15:07
  • About the language use, here in Europe all people in civil and business world use the term "week of year" meaning the week of the week-based-year. Very confusing. Originally I had hit this pitfall to choose the wrong field `weekOfYear()`. – Meno Hochschild Sep 19 '14 at 15:12
  • @MenoHochschild thanks for correction - though I'm now thoroughly confused :-) Please feel invited to edit my answer to correct my mistake. – kleopatra Sep 19 '14 at 15:36
  • I have now edited your answer and hope it helps knowing that this stuff is not easy. You can also refer to the javadoc of these fields. – Meno Hochschild Sep 19 '14 at 15:49
1

You can also use the DateTimeFormatter, looks easier for me :

LocalDate date = LocalDate.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("w");
int week = Integer.parseInt(date.format(dtf));
  • This solution is simple and elegant. Only two comments: (1) remember that the week starts on Sunday, by default; and, (2) the pattern should be "W" (uppercase) instead of "w" (lowercase, as it's on the code). More details about the patterns at [here](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html) – Almir Campos Jan 28 '20 at 02:44