如何使用 JAX-RS 在 REST 中将 Javascript 日期传递给 Java LocalDate 和 LocalDateTime

Lor*_*nzo 2 javascript java rest jax-rs angular

当我将 Javascript 日期传递给 JAX-RS 服务时,我收到:

  1. 如果目标字段是 LocalDate: Text '2018-06-04T22:00:00.000Z' could not be parsed, unparsed text found at index 10". BackEnd 对 "2018-06-04" 没问题,我试过邮差。
  2. 如果目标字段是 LocalDateTime: Text '2019-04-02T20:16:24.999Z' could not be parsed, unparsed text found at index 23. The BackEnd is OK with "2019-04-02T20:16:24",我试过邮递员。

我传递给后端的信息来自我映射到 javascript Date 对象上的 Angular Material Datepicker 组件。

我知道该字符串具有后端不相关的信息,但我不知道如何在调用 POST 之前传递正确/修改的值。

我应该传递 String 而不是 Date 对象吗?这是正确的方法吗?

有没有办法将格式为“2018-06-04T22:00:00.000Z”或“2018-06-05T00:00:00.000Z”的日期传递给LocalDate和LocalDateTime?

我使用 LocalDate 和 LocalDateTime 因为我不想处理时区。即使我更改时区,该值也应该始终相同。

在我遇到问题之前,因为服务器和客户端之间存在 1 小时的差异。因此,当我过去从 Web 服务器选择日期时,客户端可能会在组件上看到前一天,因为它从午夜开始返回 1 小时。

Bas*_*que 6

您似乎混淆了各种日期时间类型。

Java 中的日期时间类型表,包括旧版和现代版。

ISO 8601

该字符串2018-06-04T22:00:00.000Z采用标准ISO 8601格式。在Z上月底表示UTC,发音祖鲁语

ISO 8601 格式经过精心设计。它们很容易被机器解析。而且它们很容易被跨文化的人类阅读。它们的主要目的是以文本格式传达日期时间值。您确实应该使用这些格式的字符串在系统之间交换日期时间值。

Instant

Instantjava.time类中解析为 an 。

Instant instant = Instant.parse( "2018-06-04T22:00:00.000Z" ) ;
Run Code Online (Sandbox Code Playgroud)

LocalDate

LocalDate级表示没有时间的天,没有一个日期,只值时区偏移从-UTC

时区对于确定日期至关重要。对于任何给定时刻,日期因地区而异。例如,在法国巴黎午夜过后几分钟是新的一天,而在魁北克蒙特利尔仍然是“昨天” 。

如果未指定时区,JVM 会隐式应用其当前默认时区。该默认值可能会在运行时随时更改(!),因此您的结果可能会有所不同。最好将您想要/预期的时区明确指定为参数。如果关键,请与您的用户确认该区域。

以、、 或等格式指定正确的时区名称。永远不要使用 2-4 个字母的缩写,例如或因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。Continent/RegionAmerica/MontrealAfrica/CasablancaPacific/AucklandESTIST

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;
Run Code Online (Sandbox Code Playgroud)

如果您想使用 JVM 的当前默认时区,请询问它并作为参数传递。如果省略,代码读起来会变得模棱两可,因为我们不确定您是否打算使用默认值,或者您是否像许多程序员一样没有意识到这个问题。

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.
Run Code Online (Sandbox Code Playgroud)

因此,您需要决定将 UTC 中的时刻视为日期和时间的时区。

仅日期值的 ISO 8601 格式为 YYYY-MM-DD。

String output = ld.toString() ;  // Example: 2019-01-23
Run Code Online (Sandbox Code Playgroud)

…和…

LocalDate ld = LocalDate.parse( "2019-01-23" ) ;
Run Code Online (Sandbox Code Playgroud)

要在 JavaScript 中生成这样的字符串,请参阅将JavaScript 日期格式设置为 yyyy-mm-dd

OffsetDateTime

如果您想要UTC自己,请从 转换InstantOffsetDateTime。然后单独提取日期。

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

ZonedDateTime

如果您想要特定的时区,请应用 aZoneId以获取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.
Run Code Online (Sandbox Code Playgroud)

顺便说一下,请注意,ZonedDateTimetoString方法中的类通过在方括号中附加时区名称来扩展 ISO 8601 格式。一个明智的添加,但可能无法被其他一些系统正确处理。

LocalDateTime

LocalDateTime该类是用于诸如2018-06-04T22:00:00.000Zor之的输入错误类型2019-04-02T20:16:24.999Z。这些字符串输入代表一个时刻,时间线上的一个特定点。该LocalDateTime班特意没有时区或偏差的任何概念,所以它不能代表一个时刻。

人们经常误解它的性质LocalDateTime。“地方”是指任何地方或每个地方,但不是特定地方。在特定地点使用片刻ZonedDateTime

有关详细信息,请参阅Instant 和 LocalDateTime 之间的区别是什么?.


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

现在处于维护模式Joda-Time项目建议迁移到java.time类。

您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*

从哪里获得 java.time 类?

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多