title: Timestamps and time zone conversions in Java and MySQL
body: <p>I'm developing a Java application with a MySQL database on a server located in a different time zone from mine, and I am trying to decide between using DATETIME or TIMESTAMP on my database.</p>
  
  <p>After reading questions like <a href="https://stackoverflow.com/questions/409286/datetime-vs-timestamp">Should I use field &#39;datetime&#39; or &#39;timestamp&#39;?</a>, and the <a href="http://dev.mysql.com/doc/refman/5.7/en/datetime.html" rel="noreferrer">MySQL documentation</a>, I decided TIMESTAMP was better for me as it converts values to UTC for storage, and back to the current time zone for retrieval.</p>
  
  <p>Also, as user Jesper explains in <a href="https://stackoverflow.com/questions/2891361/how-to-set-time-zone-of-a-java-util-date">this</a> thread, java.util.Date objects are internally only a UTC timestamp (i.e. number of milliseconds since the Epoch), and when you do a toString() it is displayed according to your current time zone.</p>
  
  <p>For me, that looks like a good practice: storing datetimes as UTC timestamps, and then displaying them according to the current time zone.</p>
  
  <p>I was about to do it like that, but then I found this from the <a href="http://docs.oracle.com/javase/7/docs/api/java/sql/PreparedStatement.html#setTimestamp%28int,%20java.sql.Timestamp,%20java.util.Calendar%29" rel="noreferrer">Java documentation</a> for Prepared Statements and got very confused:</p>
  
  <blockquote>
    <p>void setTimestamp(int parameterIndex,
                    Timestamp x,
                    Calendar cal)
                      throws SQLException</p>
    
    <p>Sets the designated parameter to the given java.sql.Timestamp value,
    using the given Calendar object. The driver uses the Calendar object
    to construct an SQL TIMESTAMP value, which the driver then sends to
    the database. With a Calendar object, the driver can calculate the
    timestamp taking into account a custom timezone. If no Calendar object
    is specified, the driver uses the default timezone, which is that of
    the virtual machine running the application.</p>
  </blockquote>
  
  <p>Before this, I thought timestamps were by convention always in UTC. Why on earth would anyone want a localized timestamp instead of a localized <em>representation</em> of it? Wouldn't that be very confusing for everyone?</p>
  
  <p>How do these conversions work? If Java takes an UTC timestamp and converts it to an arbitrary time zone, how can it tell MySQL in which timezone it is?</p>
  
  <p>Won't MySQL assume that this timestamp is in UTC and then retrieve an incorrect localized value?</p>