在旧的Java中,我可以这样做:
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
Run Code Online (Sandbox Code Playgroud)
我想在Java 8中使用java.time.
System.out.println( LocalDate.parse("2015 1", DateTimeFormatter.ofPattern("yyyy w", Locale.US)));
Run Code Online (Sandbox Code Playgroud)
结果:
java.time.format.DateTimeParseException:无法解析文本'2015 1':无法从TemporalAccessor获取LocalDate:{WeekOfWeekBasedYear [WeekFields [SUNDAY,1]] = 1,Year = 2015},ISO类型为java.time. format.Parsed
如何在java.time中做到这一点?
此外,我不满意我必须通过Locale来确定一周的第一天:星期一和星期天.它不是乡村功能,而是日历功能.我想使用像java.time.temporal.WeekFields.ISO这样的东西来显示周从星期一开始的世界
我发现了类似的情况:https://stackoverflow.com/questions/3941700/how-to-get-dates-of-a-week-i-know-week-number
但不适用于Java 8中的java.time.此外,首先创建日期对象并稍后设置正确周的解决方案并不优雅.我想一次创建最终日期.
Men*_*ild 12
直接回答和解决方案:
System.out.println(
LocalDate.parse("2015 1",
new DateTimeFormatterBuilder().appendPattern("YYYY w")
.parseDefaulting(WeekFields.ISO.dayOfWeek(), 1)
.toFormatter()));
// output: 2014-12-29
Run Code Online (Sandbox Code Playgroud)
说明:
a)你应该使用Y代替y,因为你对ISO-8601周日期感兴趣,而不是在年代.
b)仅通过给出(基于周的)年和周数不能形成日历日期.星期几很重要,以确定指定日历周内的日期.周日期的预定义格式化程序需要缺少星期几.所以你需要使用builder-pattern构建一个专门的解析器.然后有必要通过方法告诉解析器星期几是哪一天parseDefaulting().
c)我坚持(并在这里为JSR-310辩护)说一周开始时的问题不是日历问题,而是依赖于国家的问题.美国和法国(例如)使用相同的日历,但对如何定义一周有不同的看法.可以使用明确的ISO引用字段来应用ISO-8601标准WeekFields.ISO.dayOfWeek().注意:测试表明,ChronoField.DAY_OF_WEEK与我一起使用Locale.ROOT似乎并不总是保证我在第一个版本的答案中所表明的ISO周行为(原因尚不清楚 - 对于源代码的近距离观察似乎是必要的启发不直观的行为).
d)java-time-package做得很好 - 除了星期一被指定为数字1.我会更喜欢枚举.或者使用枚举及其方法getValue().
e)侧面通知:SimpleDateFormat默认情况下行为宽松.在Java的时间包是严格,并拒绝去创造一个缺失星期几,凭空的-即使是在宽松模式(这是在我看来是个相当不错的事情).软件不应该猜到这么多,而不是程序员应该多想想什么一天的一周是正确的.在这里再次:应用程序的要求可能会在美国和法国不同,有关的权利的默认设置.