Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
273 views
in Technique[技术] by (71.8m points)

java - How to convert weeks of year to LocalDate

I have a string with both year-week e.g. "2015-40" and year-month formats e.g. "2015-08", that would like to transform into LocalDate in Scala.

I have tried using

val date = "2015-40"
val formatter = DateTimeFormatter.ofPattern("yyyy-ww") 
LocalDate.parse(date, formatter)

but end up with DateTimeParseException error. Would appreciate any help on how to do this

Thanks in advance

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
    String date = "2015-40";
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("YYYY-ww")
            .parseDefaulting(ChronoField.DAY_OF_WEEK, DayOfWeek.MONDAY.getValue())
            .toFormatter(Locale.FRANCE);
    LocalDate ld = LocalDate.parse(date, formatter);
    
    System.out.println(ld);

Sorry that I can write only Java, I trust you to translate to Scala. Output is:

2015-09-28

Why were you getting an exception? There were a couple of things missing for us to parse 2015-40 into a LocalDate:

  • A LocalDate is a calendar date, and week 40 consists of 7 days. Java doesn’t know which of those 7 days you want and refuses to make the choice for you. In my code above I have specified Monday. Any other day of the week should work.
  • A bit subtler. While to a human year 2015 and week 40 is unambiguous, the same is not always the case around New Year where week 1 may begin before New Year or week 52 or 53 extend after New Year. So a calendar year and a week number don’t always define one specific week. Instead we need the concept of a week year or week-based year. A week year lasts from week 1 inclusive no matter if that means it begins a few days before or after New Year. And it lasts until the last day of the last week, again most often a few days before or after New Year. To tell a DateTimeFormatter that we want to parse (or print) the week year we need to use upper case YYYY instead of lower case yyyy (or uuuu).

As an aside, if you can influence the format, consider 2015-W40 with a W. This is ISO 8601 format for year and week. In ISO 2015-12 denotes year and month, and many will read it this way. So to disambiguate and avoid misreading.

Edit:

In my explanation I have assumed ISO week scheme (Monday is the first day of week and week 1 is defined as the first week having at least 4 days in the new year). You may pass a different locale to the formatter builder to obtain a different week scheme.

If you are sure that your weeks follow ISO, Andreas’ suggestion in the comment is good enough that we want as part of the answer:

Alternatively, add the ThreeTen Extra library, so you can use the YearWeek class, that has a nice atDay?(DayOfWeek dayOfWeek) method for getting a LocalDate.

Link: Wikipedia article: ISO 8601


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...