代码之家  ›  专栏  ›  技术社区  ›  RoRo88

无法使用“HH:mm E d MMM YYYY”模式分析DateTimeFormatter

  •  4
  • RoRo88  · 技术社区  · 6 年前

    我正在从外部数据源检索日期/时间,返回格式为“5月5日星期六14:30”,无年份。

    我一直试图将其解析为LocalDateTime,但没有成功。返回的数据不会返回一年,因为这是一种假设,即我们总是在当前年份运行。

    //date to parse
    String time = "14:30 Sat 05 May";
    
    //specify date format matching above string
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm E d MMM YYYY") ;
    
    //we do not have a year returned but i can make the assumption we use the current year
    LocalDateTime formatDateTime = LocalDateTime.parse(time, formatter).withYear(2018);
    

    上述代码引发以下异常

    线程“main”java中出现异常。时间总体安排DateTimeParseException:无法在索引16处分析文本“14:30 Sat 05 May”

    感谢您的帮助。

    2 回复  |  直到 6 年前
        1
  •  4
  •   Basil Bourque    6 年前

    默认年份

    在中指定默认年份 DateTimeFormatter ,使用 DateTimeFormatterBuilder 通过调用初始化 parseDefaulting 并使用指定年份字段 ChronoField.YEAR

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendPattern("HH:mm E d MMM")
        .parseDefaulting(ChronoField.YEAR, 2018)  // <------
        .toFormatter(Locale.ENGLISH);
    

    使用此格式化程序而不是您的格式化程序:

    LocalDateTime.parse( "14:30 Sat 05 May" , formatter ) 
    

    我得到:

    看到了吗 code run live at IdeOne.com

    注意事项:

    • 格式模式字符串需要端到端匹配已解析的字符串。因此,当你的约会时间字符串中没有年份时,不要包括 YYYY 以您的格式模式。
    • 无论如何,不要使用大写字母 YYYY年 在这里它用于基于周的年份,仅对周数有用。如果你的字符串中有一年,你应该使用 uuuu 或小写 yyyy
    • 养成一种习惯,为格式化程序提供明确的区域设置,这样您就知道它也可以在其他计算机上运行,并且在您的计算机上运行。
        2
  •  3
  •   davidxxx    6 年前

    LocalDateTime.parse() 应为 String 表示有效日期 year 部分
    无法通过以下方式设置调用此方法后的年份:

    LocalDateTime.parse(time, formatter).withYear(2018);
    

    必须提前设定年份,否则 parse() 投掷 DateTimeParseException

    作为一种解决方法,您可以在输入中连接当前年份。

    其他注意事项:

    • 您使用的模式和文本格式的输入日期不完全匹配。
    • 您没有指定 Locale 用于分析操作。
      这意味着它将根据JVM运行的本地运行。
      为了确保它在任何情况下都能工作,您应该指定 场所

    因此,您可以尝试以下操作:

    //date to parse
    String time = "14:30 Sat 05 May";
    time +=  " " + LocalDate.now().getYear();
    
    //specify date format matching above string
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm EEE dd MMM yyyy", Locale.US) ;
    
    //we do not have a year returned but i can make the assumption we use the current year
    LocalDateTime formatDateTime = LocalDateTime.parse(time, formatter);