Преобразовать строку без ZonedId в OffsetDateTime - PullRequest
0 голосов
/ 18 мая 2018

Я хотел бы преобразовать строку в тип данных OffsetDateTime.Строка имеет следующую форму:

  2017-11-27T19:06:03

Я пробовал два подхода:

Подход 1

    public static OffsetDateTime convertString(String timestamp) {
        java.time.format.DateTimeFormatter formatter = new java.time.format.DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .append(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral('T')
            .appendValue(HOUR_OF_DAY, 2)
            .appendLiteral(':')
            .appendValue(MINUTE_OF_HOUR, 2)
            .optionalStart()
            .appendLiteral(':')
            .appendValue(SECOND_OF_MINUTE, 2)
            .toFormatter();


        return OffsetDateTime.parse(timestamp, formatter);
    }

Подход2:

    public static OffsetDateTime convertString(String timestamp) {
        java.time.format.DateTimeFormatter parser = java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
        java.time.LocalDateTime dt = java.time.LocalDateTime.parse(timestamp, parser);
        ZonedDateTime zdt = ZonedDateTime.of(dt, java.time.ZoneId.of("UTC"));
        return OffsetDateTime.from(zdt);
    }

Первый подход не работает, поскольку он жалуется на следующее:

java.time.format.DateTimeParseException: Text '2017-11-27T19:02:42 'не удалось проанализировать: невозможно получить OffsetDateTime из TemporalAccessor: {}, ISO разрешено до 2017-11-27T19: 02: 42 типа java.time.format.Parsed

ДляНасколько я понимаю, это связано с тем, что строка не имеет ZoneId.Как я могу переписать на устройстве форматирования ZoneId, чтобы игнорировать его?

Второй подход вытекает из этого вопроса и работает, но требует 2 дополнительных преобразования, я хотел бы избежать этихдополнительные преобразования.

Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Чтобы получить OffsetDateTime из строки без смещения или часового пояса, вам нужно выбрать смещение или способ его получения.Наиболее очевидный способ - если вы знаете, в каком часовом поясе должна интерпретироваться дата и время.Например:

    OffsetDateTime dateTime = LocalDateTime.parse(timestamp)
            .atZone(ZoneId.of("Asia/Chongqing"))
            .toOffsetDateTime();
    System.out.println(dateTime);

Вывод с использованием строки из вашего вопроса:

2017-11-27T19: 06: 03 + 08: 00

Не бойтесь двух преобразований из LocalDateTime в ZonedDateTime, а затем в OffsetDateTimejava.time их не только легко сделать, но и легко прочитать.

Если вы знаете смещение, просто используйте его, тогда вам потребуется только одно преобразование (я использую бессмысленное смещение для примера,так что вам придется выбрать свой собственный):

    OffsetDateTime dateTime = LocalDateTime.parse(timestamp)
            .atOffset(ZoneOffset.ofTotalSeconds(-36953));
    System.out.println(dateTime);

Вывод:

2017-11-27T19: 06: 03-10: 15: 53

Вы можете указать желаемое смещение, например, ZoneOffset.of("+08:00") или ZoneOffset.ofHours(8).

Но чтобы ответить на ваш вопрос (сейчас самое время).

Как можноЯ перезаписываю на устройстве форматирования ZoneId, чтобы его игнорировать?

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
            .parseDefaulting(ChronoField.OFFSET_SECONDS, -36953)
            .toFormatter();
    OffsetDateTime dateTime = OffsetDateTime.parse(timestamp, formatter);
    System.out.println(dateTime);

Вывод такой же, как и предыдущий (и снова вам нужно будет выбрать смещение, которое имеет смысл в вашей ситуации).

0 голосов
/ 18 мая 2018

Наконец, я решил эту проблему с помощью следующего кода:

    public static OffsetDateTime convertString(String timestamp) {
        java.time.format.DateTimeFormatter formatter = new java.time.format.DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .append(java.time.format.DateTimeFormatter.ISO_LOCAL_DATE)
            .appendLiteral('T')
            .appendValue(HOUR_OF_DAY, 2)
            .appendLiteral(':')
            .appendValue(MINUTE_OF_HOUR, 2)
            .optionalStart()
            .appendLiteral(':')
            .appendValue(SECOND_OF_MINUTE, 2)
            .toFormatter();

    return LocalDateTime.parse(timestamp, formatter)
            .atOffset(java.time.ZoneOffset.UTC);
    }
...