Parse date-only as LocalDateTime in Java 8

前端 未结 3 1652
我在风中等你
我在风中等你 2020-12-20 19:09

I need to parse a field which is sometimes given as a date and sometimes as a date/time. Is it possible to use single datatype for this using Java 8 time API? Currently, I a

相关标签:
3条回答
  • 2020-12-20 19:28

    Jose's answer using parseDefaulting is nice. There's also another alternative, if you don't want to use a DateTimeFormatterBuilder.

    First you create your formatter with an optional section - in this case, the time-of-day part, delimited by []:

    DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd[ HH:mm:ss]");
    

    Then you call parseBest, providing the String to be parsed and a list of method references:

    TemporalAccessor parsed = fmt.parseBest("1986-04-08", LocalDateTime::from, LocalDate::from);
    

    In this case, it'll first try to create a LocalDateTime, and if it's not possible, it'll try to create a LocalDate (if none is possible, it'll throw an exception).

    Then, you can check which type is returned, and act accordingly:

    LocalDateTime dt;
    if (parsed instanceof LocalDateTime) {
        // it's a LocalDateTime, just assign it
        dt = (LocalDateTime) parsed;
    } else if (parsed instanceof LocalDate) {
        // it's a LocalDate, set the time to whatever you want
        dt = ((LocalDate) parsed).atTime(LocalTime.MIDNIGHT);
    }
    

    If the result is a LocalDate, you can choose to call atStartOfDay(), as suggested by others, or change to a specific time-of-day, such as atTime(LocalTime.of(10, 30)) for 10:30 AM, for example.

    0 讨论(0)
  • 2020-12-20 19:49

    Just create custom formatter with the builder DateTimeFormatterBuilder

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("yyyy-MM-dd[ HH:mm:ss]")
            .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
            .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
            .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
            .toFormatter();
    

    This formatter uses the [] brackets to allow optional parts in the format, and adds the default values for hour HOUR_OF_DAY, minute MINUTE_OF_HOUR and second SECOND_OF_MINUTE.

    note: you can ommit, minutes and seconds, just providing the hour is enough.

    And use it as usual.

    LocalDateTime localDateTime1 = LocalDateTime.parse("1994-05-13", formatter);
    LocalDateTime localDateTime2 = LocalDateTime.parse("1994-05-13 23:00:00", formatter);
    

    This outputs the correct date time with default hours of 0 (starting of the day).

    System.out.println(localDateTime1); // 1994-05-13T00:00
    System.out.println(localDateTime2); // 1994-05-13T23:00
    
    0 讨论(0)
  • 2020-12-20 19:49

    I know its late for the answer, but it can help others...

    Since the LocalDateTime you need to set a time, otherwise you can use just the LocalDate, I searched for LocalDateTime built-in solution to handle this. I didn't found, however I used this following approach:

    // For specific date (the same as the question)
    LocalDateTime specificDate LocalDateTime.of(LocalDate.of(1986, 4, 8), LocalTime.MIN);
    

    Other examples:

    // For the start of day
    LocalDateTime startToday = LocalDateTime.of(LocalDate.now(), LocalTime.MIN));
    
    // For the end of day
    LocalDateTime endOfToday = LocalDateTime.of(LocalDate.now(), LocalTime.MAX));
    

    This way you don't need to use a formatter. :)

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