Lenient Java 8 Date parsing

前端 未结 4 2048
無奈伤痛
無奈伤痛 2020-12-18 04:47

I\'d like to parse \'2015-10-01\' with LocalDateTime. What I have to do is

LocalDate localDate = LocalDate.parse(\'2015-10-01\');
LocalDateTime          


        
相关标签:
4条回答
  • 2020-12-18 05:08

    You can try

        private static final DateTimeFormatter formatter =
                    DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss").withResolverStyle(ResolverStyle.LENIENT);
    
    0 讨论(0)
  • 2020-12-18 05:14

    A simple solution for your particular use case is to define your own format. In this example even though I have specified a single M for the month in my pattern, and a single d for the day, it still parses both examples the same.

    @Test
    public void parsing_singleDigitDates_andDoubleDigitDates_areEqual()
    {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-M-d");
    
        LocalDate dt1 = LocalDate.parse("2015-09-05", fmt);
        LocalDate dt2 = LocalDate.parse("2015-9-5", fmt);
    
        Assert.assertEquals(dt1, dt2);
    }
    

    I decided to write this answer after seeing the code soup that DateTimeFormatterBuilder requires you to write in order to solve the same problem.

    0 讨论(0)
  • 2020-12-18 05:26

    If you want to parse date String as "2015-10-01" and "2015-9-5" to LocalDateTime objects, you can build your own DateTimeFormatter using DateTimeFormatterBuilder:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                                            .appendPattern("yyyy")
                                            .appendLiteral('-')
                                            .appendValue(MONTH_OF_YEAR)
                                            .appendLiteral('-')
                                            .appendValue(DAY_OF_MONTH)
                                            .parseDefaulting(HOUR_OF_DAY, HOUR_OF_DAY.range().getMinimum())
                                            .parseDefaulting(MINUTE_OF_HOUR, MINUTE_OF_HOUR.range().getMinimum())
                                            .parseDefaulting(SECOND_OF_MINUTE, SECOND_OF_MINUTE.range().getMinimum())
                                            .parseDefaulting(NANO_OF_SECOND, NANO_OF_SECOND.range().getMinimum())
                                            .toFormatter();
    System.out.println(LocalDateTime.parse("2015-9-5", formatter));
    System.out.println(LocalDateTime.parse("2015-10-01", formatter));
    

    The variable length of each field is handled by the call to appendValue(field). Quoting the Javadoc:

    The parser for a variable width value such as this normally behaves greedily, requiring one digit, but accepting as many digits as possible.

    This means that it will be able to parse month and days formatted with 1 or 2 digits.

    To construct a LocalDateTime, we also need to provide a LocalTime to this builder. This is done by using parseDefaulting(field, value) for each field of a LocalTime. This method takes a field and a default value for that field if it is not present in the String to parse. Since, in our case, the time information will not be present in the String, the default values will be chosen, i.e. the minimum value for the range of valid values for that field (it is obtained by calling getMinimum to the ValueRange of that field; perhaps we could also hard-code 0 here).


    In the event that the String to parse might contain time information, we can use optional sections of DateTimeFormatter, like this:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                                            .appendPattern("yyyy")
                                            .appendLiteral('-')
                                            .appendValue(MONTH_OF_YEAR)
                                            .appendLiteral('-')
                                            .appendValue(DAY_OF_MONTH)
                                            .appendPattern("[ HH:mm]") // optional sections are surrounded by []
                                            .parseDefaulting(HOUR_OF_DAY, HOUR_OF_DAY.range().getMinimum())
                                            .parseDefaulting(MINUTE_OF_HOUR, MINUTE_OF_HOUR.range().getMinimum())
                                            .parseDefaulting(SECOND_OF_MINUTE, SECOND_OF_MINUTE.range().getMinimum())
                                            .parseDefaulting(NANO_OF_SECOND, NANO_OF_SECOND.range().getMinimum())
                                            .toFormatter();
    System.out.println(LocalDateTime.parse("2015-9-5", formatter));
    System.out.println(LocalDateTime.parse("2015-10-01", formatter));
    System.out.println(LocalDateTime.parse("2015-1-1 10:10", formatter));
    
    0 讨论(0)
  • 2020-12-18 05:27

    Parsing date and time

    To create a LocalDateTime object from a string you can use the static LocalDateTime.parse() method. It takes a string and a DateTimeFormatter as parameter. The DateTimeFormatter is used to specify the date/time pattern.

    String str = "1986-04-08 12:00";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
    

    Formatting date and time

    To create a formatted string out a LocalDateTime object you can use the format() method.

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    LocalDateTime dateTime = LocalDateTime.of(1986, Month.APRIL, 8, 12, 30);
    String formattedDateTime = dateTime.format(formatter); // "1986-04-08 12:30"
    

    Note that there are some commonly used date/time formats predefined as constants in DateTimeFormatter. For example: Using DateTimeFormatter.ISO_DATE_TIME to format the LocalDateTime instance from above would result in the string "1986-04-08T12:30:00".

    The parse() and format() methods are available for all date/time related objects (e.g. LocalDate or ZonedDateTime)

    0 讨论(0)
提交回复
热议问题