如何将一年中的几周转换为LocalDate [英] How to convert weeks of year to LocalDate
问题描述
我都有一个年份周的字符串,例如"2015-40"和年月格式,例如"2015-08",希望在Scala中转换为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.
我尝试使用
val date = "2015-40"
val formatter = DateTimeFormatter.ofPattern("yyyy-ww")
LocalDate.parse(date, formatter)
,但最终出现DateTimeParseException错误.希望对执行此操作有任何帮助
but end up with DateTimeParseException error. Would appreciate any help on how to do this
预先感谢
推荐答案
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);
对不起,我只能写Java,我相信您可以将其翻译成Scala.输出为:
Sorry that I can write only Java, I trust you to translate to Scala. Output is:
2015-09-28
2015-09-28
您为什么要例外?我们缺少将2015-40
解析为LocalDate
的几件事:
Why were you getting an exception? There were a couple of things missing for us to parse 2015-40
into a LocalDate
:
- A
LocalDate
是日历日期,第40周由7天组成. Java不知道您要在那7天中的哪一天,因此拒绝为您做出选择.在上面的代码中,我指定了星期一.一周中的其他任何一天都可以使用. - 有点微妙.尽管对于人类来说,2015年和第40周是明确的,但新年前后并非总是如此,因为第1周可能在新年之前开始,或者第52或53周在新年之后开始.因此,日历年和星期数并不总是定义一个特定的星期.取而代之的是,我们需要一个周年或基于周的年的概念.一周的年份从第1周开始(包括第1周),无论这意味着它在新年前后的几天开始.它持续到上周的最后一天,通常是在新年前后的几天.要告诉
DateTimeFormatter
我们要解析(或打印)一周的年份,我们需要使用大写的YYYY
而不是小写的yyyy
(或uuuu
).
- 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 caseYYYY
instead of lower caseyyyy
(oruuuu
).
顺便说一句,如果可以影响格式,请考虑将2015-W40
与W
一起使用.这是年份和星期的ISO 8601格式.在ISO中,2015-12
表示年份和月份,许多人会这样阅读.因此,要消除歧义并避免误读.
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.
在我的解释中,我假设使用ISO周计划(星期一是一周的第一天,而第1周定义为新年中至少有4天的第一周).您可以将不同的语言环境传递给格式化程序生成器,以获得不同的星期计划.
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.
如果您确定自己的星期符合ISO标准,那么安德烈亚斯(Andreas)在评论中的建议就足够了,我们希望将其作为答案的一部分:
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:
或者,添加 ThreeTen Extra 库,以便您可以使用
YearWeek
类,具有很好的
Alternatively, add the ThreeTen Extra library, so you can use the
YearWeek
class, that has a niceatDay(DayOfWeek dayOfWeek)
method for getting aLocalDate
.
链接: 维基百科文章:ISO 8601
这篇关于如何将一年中的几周转换为LocalDate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!