Reputation: 2095
I want to compare string representations of weeks, e.g. week "01/17" is before "02/17" and after "52/16".
The following code throws an exception, I guess because my string doesn't hint at the exact day of each week. However, I don't care - it could all be Mondays or Thursdays or whatever:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ww/YY", Locale.GERMANY);
LocalDate date1 = formatter.parse(str1, LocalDate::from);
Do I need to modify the parser? Or parse to some other format? Unfortunatley there is no object like YearMonth for weeks...
Upvotes: 2
Views: 320
Reputation: 338316
YearWeek.parse( "2017-W01" )
Or parse to some other format?
Yes, use another format.
Use the standard ISO 8601 formats when serializing date-time values to text. The standard includes support for week dates.
For a year-week that would be four year digits, a hyphen, a W
, and two digits for the week of the year.
2017-W01
Get clear on your definition of a “week”. The ISO 8601 definition is that:
So years run either 52 or 53 weeks long. And note that under this definition, the first few days of the year may be in the prior year when week-numbering. Likewise, the last few days of the year may be in the following year when week-numbering.
If you want to indicate a particular day within that week, append a hyphen and a single digit running 1-7 for Monday-Sunday.
Tip: To see ISO 8601 week numbers by default on your computer, you may need to adjust your OS setting. For example, on macOS set System Preferences > Language & Region > Calendar > ISO 8601 to make apps such as Calendar.app to display week numbers with this standard definition.
2017-W01-7
By the way, a couple of similar representations:
2017-123
--01-07
Note that the use of Locale
as seen in the Question is irrelevant here with the standard ISO 8601 formats.
YearWeek
Unfortunatley there is no object like YearMonth for weeks...
Ahhh, but there is such a class.
For a class to directly represent the idea of a week-year, see the correct Answer by Henrik. That Answer shows the ThreeTen-Extra library’s class YearWeek
.
The YearWeek
class can directly parse and generate strings in standard format.
YearWeek yw = YearWeek.parse( "2017-W01" );
You can compare the YearWeek
objects with methods: compareTo
, equals
, isBefore
, isAfter
.
yw.isBefore( thatYw )
The ThreeTen-Extra project offers other classes such as YearQuarter
that you may find useful.
Upvotes: 2
Reputation: 328598
One solution would be to always default to the same day, say the Monday. You could build a custom formatter for that:
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.appendPattern("ww/YY")
.parseDefaulting(ChronoField.DAY_OF_WEEK, 1)
.toFormatter(Locale.GERMANY);
You can now build LocalDate
s representing the Monday of the given week:
LocalDate d1 = LocalDate.parse("01/17", fmt);
LocalDate d2 = LocalDate.parse("52/16", fmt);
System.out.println(d1.isAfter(d2));
which prints true
because 01/17 is after 52/16.
Upvotes: 5
Reputation: 7147
I wasn't able to find a way for this to work with the DateTimeFormatter
class, but I would like to suggest a different approach.
The Threeten Extra library contains a number of classes that were deemed too specific to include in the java.time
library. One of them is the YearWeek
class you mention.
Your problem can be solved by parsing the week-number and year manually from the input-string and then invoking the YearWeek
creator-method like this:
YearWeek yw = YearWeek.of(year, monthOfYear);
Upvotes: 2