admin管理员组

文章数量:1318152

When I pass a Javascript Date to a JAX-RS service I receive:

  1. In case the target field is LocalDate: Text '2018-06-04T22:00:00.000Z' could not be parsed, unparsed text found at index 10". The BackEnd is ok with "2018-06-04", I tried with Postman.
  2. In case the target field is 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", I tried with Postman.

The information i pass to the BackEnd e from a Angular Material Datepicker ponent that I map on a javascript Date object.

I understand that the string has informations that the BackEnd do not aspect but I don't know how to pass the correct/modified value before call the POST.

Should I pass a String instead of a Date object? Is that the correct approach?

Is there a way from a date in the format "2018-06-04T22:00:00.000Z" or "2018-06-05T00:00:00.000Z" to be passed to a LocalDate and a LocalDateTime?

I used LocalDate and LocalDateTime because I do not want to deal with timezone. The value are supposed to be always the same even if I change the timezone.

Before I had a problem because there was a 1 hour difference between the server and the client. So when i used to pick a date from the web server it could happen that the client would see the day before on the ponent becasue it was going back 1 hour from midnight.

When I pass a Javascript Date to a JAX-RS service I receive:

  1. In case the target field is LocalDate: Text '2018-06-04T22:00:00.000Z' could not be parsed, unparsed text found at index 10". The BackEnd is ok with "2018-06-04", I tried with Postman.
  2. In case the target field is 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", I tried with Postman.

The information i pass to the BackEnd e from a Angular Material Datepicker ponent that I map on a javascript Date object.

I understand that the string has informations that the BackEnd do not aspect but I don't know how to pass the correct/modified value before call the POST.

Should I pass a String instead of a Date object? Is that the correct approach?

Is there a way from a date in the format "2018-06-04T22:00:00.000Z" or "2018-06-05T00:00:00.000Z" to be passed to a LocalDate and a LocalDateTime?

I used LocalDate and LocalDateTime because I do not want to deal with timezone. The value are supposed to be always the same even if I change the timezone.

Before I had a problem because there was a 1 hour difference between the server and the client. So when i used to pick a date from the web server it could happen that the client would see the day before on the ponent becasue it was going back 1 hour from midnight.

Share Improve this question edited Apr 2, 2019 at 22:31 Lorenzo asked Apr 2, 2019 at 20:23 LorenzoLorenzo 211 silver badge5 bronze badges 2
  • The string 2018-06-04T22:00:00.000Z can be correctly parsed by Instant, ZonedDateTime and OffsetDateTime. I'd suggest using ZonedDateTime for most flexible time zone parsing, and so you can easily obtain LocalDateTime and LocalDate from it. – Andreas Commented Apr 2, 2019 at 20:27
  • Warning: Note that 2018-06-04T22:00:00.000Z is probably supposed to be 2018-06-05 in a UTC+02:00 time zone. If so, you'd likely want to apply that time zone first, before obtaining the LocalDate and LocalDateTime values, so the "local" is appropriate for that time zone. --- To do that, I'd suggest using Instant.parse("2018-06-04T22:00:00.000Z").atOffset(ZoneOffset.of("+2")).toLocalDate() – Andreas Commented Apr 2, 2019 at 20:29
Add a ment  | 

1 Answer 1

Reset to default 7

You seem to be confusing the various date-time types.

ISO 8601

The string 2018-06-04T22:00:00.000Z is in standard ISO 8601 format. The Z on the end means UTC, and is pronounced Zulu.

The ISO 8601 formats are wisely designed. They are easy to parse by machine. And they are easy to read by humans across cultures. Their primary purpose is to municate date-time values in a textual format. You should indeed be using strings in these formats for exchanging date-time values between systems.

Instant

Parse as an Instant in the java.time classes.

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

LocalDate

The LocalDate class represents a date-only value without time-of-day and without time zone or offset-from-UTC.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument. If critical, confirm the zone with your user.

Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

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

If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the code bees ambiguous to read in that we do not know for certain if you intended to use the default or if you, like so many programmers, were unaware of the issue.

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

So you need to decide by what time zone you want to perceive the moment in UTC as a date and time-of-day.

The ISO 8601 format for a date-only value is YYYY-MM-DD.

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

…and…

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

To generate such a string in JavaScript, see Format JavaScript Date to yyyy-mm-dd.

OffsetDateTime

If you want UTC itself, convert from Instant to OffsetDateTime. Then extract the date alone.

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

If you want a particular time zone, apply a ZoneId to get a ZonedDateTime. Then extract the date alone.

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.

By the way, note that ZonedDateTime class in its toString method extends the ISO 8601 format by appending the name of the time zone in square brackets. A wise addition, but may not be handled properly by some other systems.

LocalDateTime

The LocalDateTime class is the wrong type to be using for an input such as 2018-06-04T22:00:00.000Z or 2019-04-02T20:16:24.999Z. These string inputs represent a moment, a specific point on the timeline. The LocalDateTime class purposely lacks any concept of time zone or offset, so it cannot represent a moment.

People frequently misunderstand the nature of LocalDateTime. The “Local” means any locality or every locality, but not a particular locality. For a moment in a specific locality, use ZonedDateTime.

For more info, see What's the difference between Instant and LocalDateTime?.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver pliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

  • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and Java SE 7
    • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

本文标签: How to pass Javascript Date to Java LocalDate and to LocalDateTime in REST with JAXRSStack Overflow