2

I am consuming a REST service and I am receiving a JSON with date attributes that do not match what is in my database. I have two fields called "initialDate" and "finalDate". In the database they are like this:

07/MAR/19 00:00:00
07/SEP/19 23:59:59

The database timezone:

select dbtimezone from dual;
+00:00

In my object, inside the Java class, the content of the attributes comes as:

public class Klass {

 @NotNull
 private Date initialDate; //initialDate.toString() "Thu Mar 07 00:00:00 CLT 2019"

 @NotNull
 private Date finalDate; // finalDate.toString() "Sat Sep 07 23:59:59:9 CLT 2019"

 public Date initialDate() {
    return this.initialDate == null ? null : new Date(initialDate.getTime());
 }

 public void setInitialDate() {
     this.initialDate = initialDate == null ? null : new Date(initialDate.getTime());
 }

 public Date finalDate() {
    return this.finalDate == null ? null : new Date(finalDate.getTime());
 }

 public void setFinalDate() {
    this.finalDate = finalDate == null ? null : new Date(finalDate.getTime());
 }

}

However, in my POSTMAN, it returns this:

initialDate: "2019-03-07T03:00:00Z",
finalDate: "2019-09-08T02:59:59Z"

Why is POSTMAN adding these 3 hours to my service response? I already try to change the timezone of Windows, but there's no difference.

deldev
  • 1,296
  • 18
  • 27

2 Answers2

2

Postman does not add anything to JSON response from a server. This representation of given date was generated by server and there is a problem. Firstly, we should start from that you should not use java.util.Date since you use Java8. There is java.time package available and you should use it to represent a time.

toString method from Date class uses default system's time zone to print date and you should not use it. java.time.LocalDateTime should work for you.

Probably your backend service uses some libraries to generate JSON response. For example, Jackson. It's configuration could be wrong this is why you see wrong dates. See below code:

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.ToString;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.TimeZone;

public class JsonTimeApp {
    public static void main(String[] args) throws IOException {
        LocalDateTime initialDate = LocalDateTime.of(2019, 3, 7, 0, 0, 0);
        LocalDateTime finalDate = LocalDateTime.of(2019, 9, 7, 23, 59, 59);

        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.registerModule(new JavaTimeModule());
        mapper.setTimeZone(TimeZone.getTimeZone("GMT"));
        // or mapper.setTimeZone(TimeZone.getTimeZone("Etc/GMT-3"));

        mapper.writeValue(System.out, new Period(initialDate, Date.from(finalDate.toInstant(ZoneOffset.UTC))));
    }
}

@Data
@AllArgsConstructor
@ToString
class Period {

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private LocalDateTime initialDate;

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private Date finalDate;
}

Above code with time zone set to GMT prints:

{
  "initialDate" : "2019-03-07T00:00:00",
  "finalDate" : "2019-09-07T23:59:59"
}

But when we change time zone to Etc/GMT-3, it prints:

{
  "initialDate" : "2019-03-07T00:00:00",
  "finalDate" : "2019-09-08T02:59:59"
}

You should check what is used to generate JSON in your case and configure properly time zone. Notice, that for initialDate we do not see this behaviour since we used java.time.LocalDateTime class instead of Date.

Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
1

After some research, I've found this article that send me to a solution.

Date format Mapping to JSON Jackson

According by the write-up, In my custom class, I set the following attributes:

DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSZ");
df.setTimeZone(TimeZone.getDefault());
this.setDateFormat(df)

In this ways, I get the result as I'd like:

{
  "initialDate" : "2019-03-07T00:00:00.000-0300",
  "finalDate" : "2019-09-07T23:59:59.000-0300"
}
deldev
  • 1,296
  • 18
  • 27