问题描述
在旧的java中,我可以这样做:
In old java I can do it in that way:
System.out.println(new SimpleDateFormat("yyyy w", Locale.UK).parse("2015 1"));
// shows Mon Dec 29 00:00:00 CET 2014
System.out.println(new SimpleDateFormat("yyyy w", Locale.US).parse("2015 1"));
// shows Mon Dec 28 00:00:00 CET 2014
我想要在Java 8中使用java.time。
I would like to use java.time in Java 8.
System.out.println( LocalDate.parse("2015 1", DateTimeFormatter.ofPattern("yyyy w", Locale.US)));
结果:
java.time。 format.DateTimeParseException:无法解析文本'2015 1':无法从TemporalAccessor获取LocalDate:{WeekOfWeekBasedYear [WeekFields [SUNDAY,1]] = 1,Year = 2015},ISO类型为java.time.format.Parsed
java.time.format.DateTimeParseException: Text '2015 1' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {WeekOfWeekBasedYear[WeekFields[SUNDAY,1]]=1, Year=2015},ISO of type java.time.format.Parsed
如何在java.time中做到这一点?
How to do it in java.time?
此外,我不满意我必须通过用于确定星期的第一天的区域设置:星期一与星期日。它不是乡村功能,而是日历功能。我想使用像java.time.temporal.WeekFields.ISO这样的东西来显示周从星期一开始的世界
Moreover, I'm not satisfied that I have to pass Locale to determine first day of week: Monday vs Sunday. It is not country feature but calendar feature. I would like to use something like java.time.temporal.WeekFields.ISO to show the world that week start with Monday
我发现了类似的情况:
I found similar case : https://stackoverflow.com/questions/3941700/how-to-get-dates-of-a-week-i-know-week-number
但不适用于Java 8中的Java.time此外,首先创建日期对象并稍后设置正确周的解决方案并不优雅。我想一次性创建最终日期。
but not for java.time in Java 8. Moreover, solution that first create a date object and later set correct week is not elegant. I want to create final date in one shot.
推荐答案
直接回答和解决方案:
System.out.println(
LocalDate.parse("2015 1",
new DateTimeFormatterBuilder().appendPattern("YYYY w")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 1)
.toFormatter()));
// output: 2014-12-29
说明:
a)你应该使用Y代替y,因为你对ISO-8601周日期感兴趣,而不是在年代。
a) You should use Y instead of y because you are interested in ISO-8601-week-date, not in year-of-era.
b)仅通过给出(基于周的)年和周数不能形成日历日期。星期几很重要,以确定指定日历周内的日期。预定义的要求缺少一周的日期。因此,您需要使用构建器模式构建专用解析器。然后有必要告诉解析器星期几是哪一天 - 通过方法 parseDefaulting()
。
b) A calendar date cannot be formed by just giving a (week-based) year and a week-number. The day of week matters to determine the day within the specified calendar week. The predefined formatter for week-dates requires the missing day-of-week. So you need to construct a specialized parser using the builder-pattern. Then it is necessary to tell the parser what day of week is wanted - via the method parseDefaulting()
.
c)我坚持(并在这里为JSR-310辩护)说,一周开始时的问题不是日历问题,而是依赖于国家的问题。美国和法国(例如)使用相同的日历,但如何定义一周有不同的观点。可以使用明确的ISO引用字段 WeekFields.ISO.dayOfWeek()
来应用ISO-8601标准。 注意:测试显示,使用 ChronoField.DAY_OF_WEEK
以及 Locale.ROOT
不会似乎总是保证ISO周的行为,正如我在第一个版本的答案中所指出的那样(原因尚不清楚 - 有必要仔细查看源代码来启发不直观的行为)。
c) I insist (and defend JSR-310 here) on saying that the question when a week starts is not a calendar issue but a country-dependent issue. US and France (as example) use the same calendar but have different views how to define a week. ISO-8601-standard can be applied using the explicitly ISO-referring field WeekFields.ISO.dayOfWeek()
. Attention: Testing has revealed that using ChronoField.DAY_OF_WEEK
together with Locale.ROOT
does not always seem to guarantee ISO-week-behaviour as indicated in my first version of this answer (the reasons are not yet clear for me - a close view of the sources seems to be necessary to enlighten the unintuitive behaviour).
d)java-time-package做得很好 - 除了星期一被指定为数字1.我会更喜欢枚举。或者使用枚举及其方法 getValue()
。
d) The java-time-package does it well - with the exception that Monday is just specified as number 1. I would have preferred the enum. Or use the enum and its method getValue()
.
e)附加声明: SimpleDateFormat
默认情况下行为宽松。 java-time-package更加严格,拒绝用空气来创造一个缺少的星期几 - 即使是在宽松的模式下(在我看来这是一件好事)。软件不应该如此猜测,相反,程序员应该更多地考虑哪一天是正确的。再次:在美国和法国,关于正确的默认设置,应用程序要求可能会有所不同。
e) Side notice: SimpleDateFormat
behaves leniently by default. The java-time-package is stricter and rejects to invent a missing day-of-week out of thin air - even in lenient mode (which is in my opinion rather a good thing). Software should not guess so much, instead the programmer should think more about what day-of-week is the right one. Again here: The application requirements will probably differ in US and France about the right default setting.
这篇关于如何使用java.time从年份和星期解析字符串中的日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!