Search code examples
javalocalizationjava-timelocaldatetimedatetimeformatter

Java DateTimeFormatter and LocalDateTime.parse trouble


Sorry for this question being basic, and for not being able to show the things I've tried. But as of now, I'm having trouble getting my head wrapped around Javas DateTimeFormatter and LocalDateTime.

The code that's not working, but obviously has been working before some change I don't know about (I just got this code thrown in my lap):

public getDateForIception() {
    String tid = driver.findElement(By.cssSelector("div.hendelse-tid.hb-tekst--ingenBryting"))
        .getText().replaceAll("(?<=[A-Za-z]{3})[.a-z]{1,2}", "");
    if(tid.split("\\.")[0].length() == 1) {
        tid = "0" + tid;
    }

    return DatoUtils.parseDatoLocalDateTime(tid,  "dd. MMM yyyy HH:mm");
}

Not entirely sure what the point of the replacing of characters etc. are, but in this case the if() isn't executedm and the "tid" variable is unchanged. Just kept it here for possible reference.

public static LocalDateTime parseDatoLocalDateTime(String datoString, String pattern) {
    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .parseCaseInsensitive()
        .appendPattern(pattern)
        .toFormatter(Locale.forLanguageTag("no"));
    return LocalDateTime.parse(datoString, formatter);
}

I suspect there's been some change in the format that's read from the page, so that the parsing fails. But the error message makes little sense to me:

java.time.format.DateTimeParseException: Text '15. jun 2022 19:51' could not be parsed at index 4

Ideas or solutions are greately appreciated.


Solution

  • In the formatter builder, Norwegian language is set by this line

    .toFormatter(Locale.forLanguageTag("no"));
    

    You can set locale to English by using the language tag en or you should provide Norwegian month names (with a dot at the end for shortened variants) like jan., feb., mar., apr., mai (the dot is not required since it's a full month name), etc.


    EDIT: After additional research, I've found that you can parse Norwegian months without an additional dot at the end. To accomplish that, you need to use a standalone format for a month (LLL instead of MMM).

    So, your code will look like that

    public getDateForIception() {
        String tid = driver.findElement(By.cssSelector("div.hendelse-tid.hb-tekst--ingenBryting"))
            .getText().replaceAll("(?<=[A-Za-z]{3})[.a-z]{1,2}", "");
        if(tid.split("\\.")[0].length() == 1) {
            tid = "0" + tid;
        }
    
        return DatoUtils.parseDatoLocalDateTime(tid,  "dd. LLL yyyy HH:mm");
    }
    
    public static LocalDateTime parseDatoLocalDateTime(String datoString, String pattern) {
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .appendPattern(pattern)
            .toFormatter(Locale.forLanguageTag("no"));
        return LocalDateTime.parse(datoString, formatter);
    }