nbpeth
nbpeth

Reputation: 3148

Spring hibernate unwanted timezone adjustment

I have a simple service that takes a date in as a String (amongst other fields) and saves it to a mySql database. I am using Spring Boot with Hibernate. If I post JSON with {"expenseDate":"04/02/2017"} the date that is being captured after the jackson mapping is "2017-04-01 19:00:00".

Incidentally, if I look at the row in the database, the date is "2017-04-02" just as I would expect. When I query the service, the date that comes back in the json is correct, but when I dump out the rows from the database, they all return the correct day minus six hours.

I live in the central time zone, so my guess is that the date in the database is UTC and Spring is taking six hours off for being in central time.

Controller:

@PostMapping("/expenses")
public ResponseEntity<Expense> submitExpense(@RequestBody Expense expense) throws BadHttpRequest {
    expenseService.saveExpense(expense);
    return new ResponseEntity<>(expense, HttpStatus.CREATED);
}

Entity:

@Entity
public class Expense {
@Id
@GeneratedValue
Integer id;
Double cost;
String location;
String expenseType;
String description;

@JsonFormat(pattern = "MM/dd/yyyy")
Date expenseDate;

I tried @JsonFormat(pattern = "MM/dd/yyyy", timezone = "UTC") on the date field but it changed nothing.

I also tried constructing the date from the view using the date parts and passing it as a long down to the service, but the result is the same. clearly I'm missing something excruciatingly vital and, likely, simple.

any thoughts?

Upvotes: 0

Views: 856

Answers (2)

uncaught_exception
uncaught_exception

Reputation: 1078

You should set the "timezone" to whatever timezone you expect the incoming date to be in.

public class Data {

    @JsonFormat(pattern = "MM/dd/yyyy", timezone="GMT-04:00")
    Date date;

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}

public class Main {

    public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {

        ObjectMapper mapper = new ObjectMapper();
        Data data = mapper.readValue("{\"date\" : \"04/02/2017\"}", Data.class);
        System.out.println(data.date);
    }
}

Output

Sun Apr 02 00:00:00 EDT 2017

// I am located in EDT

If I assume the incoming date is in UTC

@JsonFormat(pattern = "MM/dd/yyyy", timezone="UTC")
Date date; 

Output

Sat Apr 01 20:00:00 EDT 2017

By default it appears to be considering the date as UTC. In your case if you are in CST you should consider setting Central Time timezone (I believe US/Central).

Note If your date inputs can come from clients in different timezones that will be another discussion. You will most likely have to define a contract that client enters a date in a particular timezone OR explicitly specify a timezone as additional input OR have your client side (if one exists) do a conversion to a specific timezone that your server-side expects.

Upvotes: 1

Allen Wang
Allen Wang

Reputation: 11

There is a database connection url parameter called serverTimezone you may need put.

Upvotes: 1

Related Questions