Как передать дату Javascript в Java LocalDate и в LocalDateTime в REST с JAX-RS - PullRequest
0 голосов
/ 02 апреля 2019

Когда я передаю дату Javascript в службу JAX-RS, я получаю:

  1. Если целевым полем является LocalDate: Text '2018-06-04T22: 00: 00.000Z', невозможнобыть проанализирован, неразобранный текст найден в индексе 10 ". BackEnd в порядке с" 2018-06-04 ", я попытался с почтальоном.
  2. В случае, если целевое поле - LocalDateTime: Text '2019-04-02T20: 16: 24.999Z 'невозможно проанализировать, найден неразобранный текст по индексу 23. BackEnd в порядке с "2019-04-02T20: 16: 24", я пытался с Почтальоном.

информация, которую я передаю в BackEnd, поступает от компонента Angular Material Datepicker, который я сопоставляю с объектом Date в javascript.

Я понимаю, что в строке есть информация, которую BackEnd не имеет, но я не знаю, как передатьправильное / измененное значение перед вызовом POST.

Должен ли я передавать строку вместо объекта Date? Это правильный подход?

Есть ли какой-либо путь из даты в формате "2018-06-04T22: 00: 00.000Z "или" 2018-06-05T00: 00: 00.000Z "будетпередал LocalDate и LocalDateTime?

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

До того, как у меня возникла проблема, потому что между сервером и клиентом была разница в 1 час.Поэтому, когда я выбирал дату на веб-сервере, может случиться так, что клиент увидит день раньше на компоненте, потому что он возвращается на 1 час с полуночи.

1 Ответ

1 голос
/ 02 апреля 2019

Вы, кажется, путаете различные типы даты и времени.

Table of date-time types in Java, both legacy and modern.

ISO 8601

Строка 2018-06-04T22:00:00.000Z в стандартном формате ISO 8601 . Z в конце означает UTC, и произносится Zulu .

Форматы ISO 8601 разработаны с умом. Их легко разобрать на машине. И они легко читаются людьми в разных культурах. Их основная цель состоит в том, чтобы передавать значения даты и времени в текстовом формате. Вы действительно должны использовать строки в этих форматах для обмена значениями даты и времени между системами.

Instant

Разобрать как Instant в java.time классах.

Instant instant = Instant.parse( "2018-06-04T22:00:00.000Z" ) ;

LocalDate

Класс LocalDate представляет значение только для даты без времени суток и без часового пояса или смещения от UTC .

Часовой пояс имеет решающее значение при определении даты. В любой момент времени дата меняется по всему земному шару в зависимости от зоны. Например, через несколько минут после полуночи в Париж Франция - это новый день, но все еще "вчера" в Монреаль Квебек .

Если часовой пояс не указан, JVM неявно применяет свой текущий часовой пояс по умолчанию. Это значение по умолчанию может измениться в любой момент во время выполнения (!), Поэтому ваши результаты могут отличаться. Лучше явно указать желаемый / ожидаемый часовой пояс в качестве аргумента. Если критично, подтвердите зону с вашим пользователем.

Укажите собственное имя часового пояса в формате Continent/Region, например America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте 2-4 буквенные сокращения, такие как EST или IST, так как они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

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

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Так что вам нужно решить, по какому часовому поясу вы хотите воспринимать момент в UTC как дату и время суток.

Формат ISO 8601 для значения только для даты - ГГГГ-ММ-ДД.

String output = ld.toString() ;  // Example: 2019-01-23

... и ...

LocalDate ld = LocalDate.parse( "2019-01-23" ) ;

Чтобы создать такую ​​строку в JavaScript, см. Формат JavaScript Дата в гггг-мм-дд .

OffsetDateTime

Если вы хотите UTC, конвертируйте из Instant в OffsetDateTime. Затем извлеките одну дату.

OffsetDateTime odt = instant.atOffset( ZoneOffsetUTC ) ;  // Convert to the more flexible `OffsetDateTime` class from `Instant` class.
LocalDate ld = odt.toLocalDate() ;                        // Extract a date-only value.

ZonedDateTime

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

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;    // Adjust from UTC to a time zone.
LocalDate ld = zdt.toLocalDate() ;           // Extract a date-only value, dropping the time-of-day and the time zone.

Кстати, обратите внимание, что класс ZonedDateTime в своем методе toString расширяет формат ISO 8601, добавляя имя часового пояса в квадратных скобках. Мудрое дополнение, но не может быть обработано должным образом некоторыми другими системами.

LocalDateTime

Класс LocalDateTime - это неправильный тип , который будет использоваться для ввода, такого как 2018-06-04T22:00:00.000Z или 2019-04-02T20:16:24.999Z. Эти строковые входы представляют момент, конкретную точку на временной шкале. Класс LocalDateTime намеренно лишен какой-либо концепции часового пояса или смещения, поэтому он не может представлять момент.

Люди часто неправильно понимают природу LocalDateTime. «Местный» означает любой населенный пункт или каждый населенный пункт, но не конкретный населенный пункт. На мгновение в определенной местности используйте ZonedDateTime.

Подробнее см. В чем разница между Instant и LocalDateTime? .


О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar и & SimpleDateFormat.

Чтобы узнать мсм. Учебное пособие по Oracle .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .

Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на java.time классы.

Вы можете обмениваться java.time объектами напрямую с вашей базой данных.Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии.Нет необходимости в строках, нет необходимости в java.sql.* классах.

Где получить классы java.time?

  • Java SE 8 , Java SE 9 , Java SE 10, Java SE 11 и более поздних версий - часть стандартного API Java с связанной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и JavaSE 7
    • Большинство функций java.time перенесено в Java 6 & 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии пакетов Android для реализации java.time классы.
    • Для более ранних версий Android (<26) проект <a href="https://github.com/JakeWharton/ThreeTenABP" rel="nofollow noreferrer"> ThreeTenABP адаптируется ThreeTen-Backport (упомянуто выше).См. Как использовать ThreeTenABP… .

ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти некоторые полезные классы, такие как Interval, YearWeek, YearQuarter и more .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...