Лек анализ на дата на Java 8

Бих искал да анализирам „2015-10-01“ с LocalDateTime. Това, което трябва да направя е

LocalDate localDate = LocalDate.parse('2015-10-01');
LocalDateTime localDateTime = localDateTime.of(localDate, LocalTime.MIN);

Но бих искал да го анализирам с едно преминаване като

// throws DateTimeParseException
LocalDateTime date = LocalDateTime.parse('2015-10-01', DateTimeFormatter.ISO_LOCAL_DATE);

Също така малка разлика в низ също хвърля изключението.

// throws DateTimeParseException
LocalDate localDate = LocalDate.parse("2015-9-5", DateTimeFormatter.ISO_LOCAL_DATE);

Мога ли да анализирам снизходително низове за дата с Java 8 API за дата?


person Sanghyun Lee    schedule 06.10.2015    source източник


Отговори (4)


Ако искате да анализирате низ от дата като "2015-10-01" и "2015-9-5" до LocalDateTime обекти, можете да създадете свой собствен DateTimeFormatter с помощта на 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));

Променливата дължина на всяко поле се обработва от извикването на appendValue(field). Цитирайки Javadoc:

Анализаторът за стойност с променлива ширина като тази обикновено се държи алчно, изисквайки една цифра, но приема възможно най-много цифри.

Това означава, че ще може да анализира месеца и дните, форматирани с 1 или 2 цифри.

За да конструираме LocalDateTime, ние също трябва да предоставим LocalTime на този строител. Това се прави с помощта на parseDefaulting(field, value) за всяко поле на LocalTime. Този метод приема поле и стойност по подразбиране за това поле, ако не присъства в низа за анализ. Тъй като в нашия случай информацията за времето няма да присъства в низа, ще бъдат избрани стойностите по подразбиране, т.е. минималната стойност за диапазона от валидни стойности за това поле (тя се получава чрез извикване на getMinimum към ValueRange от това поле; може би бихме могли също да кодираме твърдо 0 тук ).


В случай, че низът за анализ може да съдържа информация за времето, можем да използваме незадължителни секции на DateTimeFormatter, като това:

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));
person Tunaki    schedule 06.10.2015

Просто решение за вашия конкретен случай на употреба е да дефинирате свой собствен формат. В този пример, въпреки че съм посочил едно M за месеца в моя модел и едно d за деня, той все още анализира двата примера по същия начин.

@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);
}

Реших да напиша този отговор, след като видях кодовата супа, която DateTimeFormatterBuilder изисква да напишете, за да разрешите същия проблем.

person Brad    schedule 28.09.2018

Анализ на дата и час

За да създадете LocalDateTime обект от низ, можете да използвате статичния LocalDateTime.parse() метод. Той приема низ и DateTimeFormatter като параметър. DateTimeFormatter се използва за указване на шаблона за дата/час.

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

Форматиране на дата и час

За да създадете форматиран низ от LocalDateTime обект, можете да използвате метода format().

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"

Имайте предвид, че има някои често използвани формати за дата/час, предварително дефинирани като константи в DateTimeFormatter. Например: Използването на DateTimeFormatter.ISO_DATE_TIME за форматиране на екземпляра LocalDateTime от по-горе ще доведе до низ "1986-04-08T12:30:00".

Методите parse() и format() са налични за всички обекти, свързани с дата/час (напр. LocalDate или ZonedDateTime)

person Ankush soni    schedule 06.10.2015
comment
Съжалявам, но моля, прочетете внимателно въпроса. Не питам за употребата. - person Sanghyun Lee; 06.10.2015

Можете да опитате

    private static final DateTimeFormatter formatter =
                DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss").withResolverStyle(ResolverStyle.LENIENT);
person super1ha1    schedule 01.03.2018
comment
Благодаря за отговора, но не това исках. За целта трябва да предоставя текста в правилен формат. Това е снизходително по различен начин. - person Sanghyun Lee; 01.03.2018