猿问

无法从基于周的字符串的 TemporalAccessor 获取 LocalDate

我正在尝试将格式为“YYYYww”(例如 201901)的简单字符串解析为 LocalDate,但我的尝试都没有成功。

我试图通过简单地使用模式“YYYYww”以及通过手动将值附加到 FormatterBuilder 来解析它。由于我的输入字符串不包含一天,我还将格式化程序配置为默认为星期日。

这是对我来说失败的代码,运行 Java 8 (IBM JRE 8.0.5.25)。

    formatter1(); // Unable to obtain LocalDate from TemporalAccessor

    formatter2(); // Text '201901' could not be parsed at index 0

    formatter3(); // Text '201901' could not be parsed at index 6

}


public static void formatter1() {

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()

            .appendValue(WeekFields.ISO.weekBasedYear(), 4, 4, SignStyle.NEVER)

            .appendValue(WeekFields.ISO.weekOfYear(), 2, 2, SignStyle.NEVER)

            .parseDefaulting(WeekFields.ISO.dayOfWeek(), DayOfWeek.SUNDAY.getValue())

            .toFormatter();


    LocalDate.parse("201901", formatter);

}


public static void formatter2() {

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()

            .appendPattern("YYYYww")

            .parseDefaulting(WeekFields.ISO.dayOfWeek(), DayOfWeek.SUNDAY.getValue())

            .toFormatter();


    LocalDate.parse("201901", formatter);

}


public static void formatter3() {

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()

            .parseLenient()

            .appendPattern("YYYYww")

            .parseDefaulting(WeekFields.ISO.dayOfWeek(), DayOfWeek.SUNDAY.getValue())

            .toFormatter();


    LocalDate.parse("201901", formatter);

}

如示例代码中所示,我收到不同的错误消息,尤其是第一个示例让我感到困惑,因为 TemporalAccessor 包含基于周的年份、一年中的星期和工作日,这应该足以构造 LocalDate .



偶然的你
浏览 337回答 4
4回答

RISEBY

这适用于 Java 8 及更高版本:    DateTimeFormatter formatter = new DateTimeFormatterBuilder()             .appendValue(WeekFields.ISO.weekBasedYear(), 4)             .appendValue(WeekFields.ISO.weekOfWeekBasedYear(), 2)             .parseDefaulting(WeekFields.ISO.dayOfWeek(), DayOfWeek.SUNDAY.getValue())             .toFormatter();     System.out.println(LocalDate.parse("201901", formatter));输出是:2019-01-06我已经在 Oracle Java 1.8.0_101 上进行了测试。我还没有安装任何 IBM Java。让它工作的关键是使用weekOfWeekBasedYear()而不是weekOfYear(). 我的其他变化是装饰性的。WeekFields.ISO.weekOfYear()通过计算一年中的星期一来定义周数,这不是您想要的,因为根据 ISO,第 1 周可能从上一年年底(12 月 29 日到 31 日)附近的星期一开始。因此它也不能很好地与基于周的 year一起使用,并且 Java 拒绝将两者一起使用来标识周。在 Java 9 上,您的formatter2()和formatter3()也都可以工作(在 Oracle Java 9.0.4 上测试过)。Java 8 中似乎存在一个错误,相邻字段解析对YYYYww. 不过,我已经搜索了 Oracle Java Bug 数据库,但没有找到错误描述。国际标准化组织 8601ISO 8601 是规定您正在使用的周的定义的标准,它还定义了周的格式。它就像2012-W48。因此,除非您有充分且非常具体的理由不这样做,否则这是您应该使用的格式,尤其是在与任何外部系统交换数据时。它还恰好消除了 Java 8 上的相邻字段解析问题。DateTimeFormatter formatter = new DateTimeFormatterBuilder()             .appendPattern("YYYY-'W'ww")             .parseDefaulting(WeekFields.ISO.dayOfWeek(), DayOfWeek.SUNDAY.getValue())             .toFormatter();     System.out.println(LocalDate.parse("2019-W01", formatter));2019-01-06

侃侃尔雅

据我所知你不能那样做。据我所知,您的代码有两个问题。首先是 aLocalDate没有足够的信息,因为您的代码不知道它应该解析到哪个工作日。二是略显怪异的字段的使用。如果你只是使用 Chrono 字段,你应该没问题。您也可以调整您的模式以包含空格或破折号,因为解析似乎不喜欢它在一个数字中 - 不知道为什么例如,您可以执行以下操作:DateTimeFormatter formatter = new DateTimeFormatterBuilder()        .appendValue(ChronoField.YEAR, 4, 4, SignStyle.NEVER)        .appendValue(ChronoField.ALIGNED_WEEK_OF_YEAR, 2, 2, SignStyle.NEVER)        .parseDefaulting(ChronoField.DAY_OF_WEEK, DayOfWeek.SUNDAY.getValue())        .toFormatter();LocalDate d = LocalDate.parse("201933", formatter);但是,使用周数似乎不是一个好的选择。

天涯尽头无女友

您可以使用YearMonthpublic static void main(String[] args) {     System.out.println(YearMonth.parse("201901", DateTimeFormatter.ofPattern("yyyyMM"))); }输出2019-01

慕桂英546537

那么 2019 年的第一周并没有给你一个特定的日期。您需要添加一周中的特定日期。我跑了这个:System.out.println(LocalDate.parse("2019-01-01", DateTimeFormatter.ofPattern("YYYY-ww-ee")));并得到"2018-12-30"(那是因为2019年1月1日是星期二,即一周的第三天,所以2019年第一周的第一天实际上是"2018-12-30")。请注意,由于某种原因没有破折号,"-"它不起作用。
随时随地看视频慕课网APP

相关分类

Java
我要回答