0

I been receiving date in the "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" format from JSON input, which gets converted to a DTO by Spring it self. But when converted to OffsetDateTime instance, this loses the information about Offset in the created OffsetDateTime instance. For example we are passing following in the Postman invoking an API, this results in the parsing and object getting created but the object doesn't have offset set in it.

Below is the example of the "2019-03-21T06:43:56.235+11:00" date when parsed it results in the date with OffsetDateTime instance but it doesn't have the +11:00 as the offset. When I directly parse this string using DateTimeFormatter I am able to get the offset populated.

below is the code that uses DateTimeFormatter.

OffsetDateTime.parse(offSetDateTimeString, DateTimeFormatter.ofPattern(DATE_PATTERN))

The DATE_PATTER = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX".

Please guide.

Thank you.

UPDATE

My DO has following objects:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

private String name;

// THis won't work as it doesn't support timestamp.
// @Column(columnDefinition = "TIMESTAMP WITH TIME ZONE")
// private LocalDateTime localDateTime;

@Column(columnDefinition = "TIMESTAMP WITH TIME ZONE")
private ZonedDateTime zonedDateTime;

@Column(columnDefinition = "TIMESTAMP WITH TIME ZONE")
private OffsetDateTime offSetDateTime;

While DTO also has same fields with SAME data types.

Bilbo Baggins
  • 2,899
  • 10
  • 52
  • 77
  • no, it is not that simple :) :) , The code that you are asking is already within spring, not written by me. When you use @RequestBody and provide a DTO, spring does the conversion of incoming JSON – Bilbo Baggins Mar 22 '19 at 11:30
  • Kindly ask for more clarification if you don't understand the question, the question it self has some value, I have done my work, I am stuck hence asking here. :) :) please don't down vote without any reasons, ask for more information I would provide. – Bilbo Baggins Mar 22 '19 at 11:31
  • 1
    Take a look on [Spring Boot Jackson date and timestamp Format](https://stackoverflow.com/questions/55256567/spring-boot-jackson-date-and-timestamp-format). Maybe you need to include `JavaTimeModule`. – Michał Ziober Mar 22 '19 at 12:09
  • Are you saying that you are receiving an `OffsetDateTime` without offset? That sounds like a contradiction in terms. `yourOffsetDateTime,getOffset()`has got to return *something* (and not null according to the docs). You are not by any chance receiving an object with offset `Z` (zero)? – Ole V.V. Mar 22 '19 at 12:12
  • I am receiving only Z , when I debug and check for the offset, ideally it should return the +11:00 as offset, I understand this is very confusing for me as well. – Bilbo Baggins Mar 22 '19 at 12:37
  • @MichałZiober I have enabled JSR-310 related to this. – Bilbo Baggins Mar 22 '19 at 12:43
  • "OffsetDateTime.parse(offSetDateTimeString, DateTimeFormatter.ofPattern(DATE_PATTERN))" is your code or springs? – DCO Mar 22 '19 at 13:28
  • 1
    A side note, it seems you're using postgres, I highly recommend not using ZonedDateTime as a column. Check this question: https://stackoverflow.com/questions/5876218/difference-between-timestamps-with-without-time-zone-in-postgresql and I summarize a comment: 'But readers should understand that both data types, timestamp with time zone and timestamp without time zone, in Postgres do *not actually store time zone information. Something of a misnomer: "without tz" means "ignore offset when inserting data" and "with tz" means "use offset to adjust to UTC"' – Sebastiaan van den Broek Mar 22 '19 at 18:20
  • It will just lead to confusion for you. It's probably better to save an Instant. You're going to need timezone information later to display it to the user again. Note that postgres interprets the incoming datetime based on the timezone your Java application is running it. Yes it's messy so inform yourself, it's easy to make mistakes here. – Sebastiaan van den Broek Mar 22 '19 at 18:22
  • Btw, this may very well be your answer if you're going by your saved DO to see whether the offset is still there (instead of checking the DTO before it is even converted) – Sebastiaan van den Broek Mar 22 '19 at 18:31
  • @SebastiaanvandenBroek I have oracle DB, and I am doing a POC with ZonedDateTime and OffsetDateTime (I am planning to use OffsetDateTime) . – Bilbo Baggins Mar 23 '19 at 06:22

1 Answers1

0

Okay, here is what I did to solve this issue.

  1. Instead of accepting OffsetDateTime in DTO, I accepted String. For this I required changes to be done in the Mapper (MapStruct). I defined custom String to OffsetDateTime mapper classes and specified them in the uses in @Mapper.
  2. This solved my parsing related issue, then moving on to the DB, I noticed a couple of things.

    1. TIMESTAMP WITH TIME ZONE doesn't store the date in the exact given format.
    2. You need to use the ZoneId to convert the time to appropriate timezone. And you have to write custom Utility for this kind of conversion.
    3. We need to obtain now the relevant timezone's zoneId object, which we have currently obtained from the incoming request.

This is the update as of now. Posting this for other's reference. Thank you all for guiding.

Bilbo Baggins
  • 2,899
  • 10
  • 52
  • 77