Как получить дату и время со смещением и без него? - PullRequest
0 голосов
/ 14 января 2020

В настоящее время мой метод может анализировать и форматировать дату и время со смещением.

Хотя я сталкивался с JUnit, я обнаружил - для многих людей довольно очевидную ошибку - я могу анализировать его, только если он содержит смещение.

Я либо получаю Unable to obtain OffsetDateTime from TemporalAccessor, либо я не могу разобрать время со смещением.

Пока мой код:

Рабочий ввод: "2020-01-12T10:30-06:00"

Не работает ввод: "2020-01-12T10:30"

OffsetDateTime offsetDateTime = OffsetDateTime.parse(date, buildIso8601Formatter());
Instant instant = offsetDateTime.toInstant();

return LocalDateTime.ofInstant(instant, ZoneOffset.UTC);

Он отлично работает для даты и времени со смещением, но не наоборот.

В конце я хочу иметь возможность разбирать дату / время со смещением / без смещения тем же методом.

Ответы [ 2 ]

3 голосов
/ 14 января 2020

Момент

Рабочий вход: «2020-01-12T10: 30-06: 00»

Не рабочий вход: «2020-01-12T10: 30»

Эти входы - два очень разных животных. Первый представляет момент, второй нет. Первый определяет конкретную c точку на временной шкале, второй - нет.

Второму не хватает критического контекста часового пояса или смещения от UT C. Таким образом, мы не знаем, представляет ли второй вход 10:30 в 12-м в Токио, Япония, или 10:30 в Тунисе, Тунис, или 10:30 в Толедо, штат Огайо, США - все это очень разные моменты, с интервалом в несколько часов.

Неисправный источник данных

Если у вас есть источник входных данных, который произвольно пропускает информацию о смещении / зоне, то у вас нет проблем с вашим собственным Java программированием, вашим источником данных есть проблема.

Представьте себе источник данных, который предоставил ряд денежных сумм, некоторые суммы указывали валюту канадских долларов, евро или японских иен, в то время как некоторые суммы произвольно не указывали валюту. Очевидно, что это будет считаться ошибочными данными, которые должны быть исправлены в источнике.

Если вы действительно хотите работать с этими ошибочными данными, просто посмотрите на наличие знака плюс или минус. Если найдено, проанализируйте как OffsetDateTime. Если опущен, анализировать как LocalDateTime.

if( input.contains( "+" ) || input.contains( "-" ) ) {
    OffsetDateTime odt = OffsetDateTime.parse( input ) ;
} else {
    LocalDateTime ldt = LocalDateTime.parse( input ) ;
}

В качестве альтернативы, попытаться выполнить синтаксический анализ как один тип. Если выброшено DateTimeParseException, попробуйте другой тип.

Если вы уверены , вход без пропуска был предназначен для определенной зоны или смещения, примените это смещение или зона.

ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;

Если вы хотите потерять часовой пояс, сохраняя смещение от UT C, чтобы сопоставить его с другими OffsetDateTime объектами, позвоните toOffsetDateTime.

OffsetDateTime odt = zdt.toOffsetDateTime() ;

К вашему сведению, разница между часовым поясом и простым смещением … Смещение всего на несколько часов-минут-секунд впереди (положительного) или позади (отрицательного) UT C, главный меридиан . Часовой пояс гораздо больше. Часовой пояс - это история прошлых, настоящих и будущих изменений смещения, используемого людьми определенного региона, как установлено (и часто изменено!) Их политиками.

enter image description here

2 голосов
/ 14 января 2020

Вы можете проанализировать String, который имеет смещение непосредственно к OffsetDateTime, но вы не можете сделать это с String, у которого нет информации о смещении или часовом поясе.

Сделайте это так, как показано здесь:

public static void main(String[] args) {
    String working = "2020-01-12T10:30-06:00";
    String notWorking = "2020-01-12T10:30";

    // directly parse the String with an offset to an OffsetDateTime
    OffsetDateTime offsetDateTime = OffsetDateTime.parse(working, 
            DateTimeFormatter.ISO_OFFSET_DATE_TIME);
    // parse the String without an offset to a LocalDateTime first
    LocalDateTime localDateTime = LocalDateTime.parse(notWorking, 
            DateTimeFormatter.ISO_LOCAL_DATE_TIME);

    // print them just to see the results
    System.out.println(offsetDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
    System.out.println(localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));

    // then convert the LocalDateTime to an OffsetDateTime by adding a ZoneOffset to it
    OffsetDateTime fromLocalDateTime = localDateTime.atOffset(ZoneOffset.of("-06:00"));
    // and print that
    System.out.println(fromLocalDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
}

В результате получается

2020-01-12T10:30:00-06:00
2020-01-12T10:30:00
2020-01-12T10:30:00-06:00
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...