Java MySQL Timestamp time zone problems

后端 未结 3 682
遇见更好的自我
遇见更好的自我 2021-01-02 16:20

I have a java.util.Date object, and I need to insert it into a datetime field in MySQL in UTC format.

java.util.Date date = myDate         


        
3条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-02 16:56

    Jordan, actually you had the right idea. The problem is there's a bug in MySQL JDBC driver and the Calendar argument is completely ignored by default. Look at the source code for PreparedStatement to really see what's going on.

    Notice it format's the Timestamp using the JVM's time zone. This will only work if your JVM is using UTC time zone. The Calendar object is completely ignored.

    this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss''", Locale.US);
    timestampString = this.tsdf.format(x);
    

    In order for MySQL to use the Calendar argument, you have to disable the legacy date/time code with the following connection option:

    useLegacyDatetimeCode=false
    

    So you might use it when connecting to the database like this:

    String url = "jdbc:mysql://localhost/tz?useLegacyDatetimeCode=false"
    

    If you disable the legacy datetime code using the above line, then it WILL render your Timestamp in the target Calendar's time zone:

    if (targetCalendar != null) {
        targetCalendar.setTime(x);
        this.tsdf.setTimeZone(targetCalendar.getTimeZone());
    
         timestampString = this.tsdf.format(x);
    } else {
        this.tsdf.setTimeZone(this.connection.getServerTimezoneTZ());
        timestampString = this.tsdf.format(x);
    }
    

    It's pretty easy to see what's going on here. If you pass in a Calendar object, it will use this when formatting the data. Otherwise, it will use the database's time zone to format the data. Strangely, if you pass in a Calendar, it will also set the time to the given Timestamp value (which seems to be pointless).

提交回复
热议问题