variable una insertar ingresar hora guardar fecha desde declarar con como java mysql

una - ¿Cómo almacenar un java.util.Date en un campo de marca de tiempo MySQL en la zona horaria UTC/GMT?



insertar hora en mysql desde java (5)

Usé un nuevo objeto Date () para llenar un campo en un MySQL DB, pero el valor real almacenado en ese campo está en mi zona horaria local.

¿Cómo puedo configurar MySQL para almacenarlo en la zona horaria UTC / GMT?

Creo que la configuración de la cadena de conexión ayudará, pero no sé cómo. Hay muchas propiedades en la cadena de conexión como useTimezone, serverTimzone, useGmtMillisForDatetimes, useLegacyDatetimeCode, ...


Bueno, si estamos hablando de usar PreparedStatement , hay una forma de setDate en la que puede pasar un calendario configurado a una zona horaria particular.

Por ejemplo, si tiene un PreparedStatement llamado stmt, una fecha con fecha y suponiendo que la fecha es el segundo parámetro:

stmt.setDate(2, date, Calendar.getInstance(TimeZone.getTimeZone("GMT")));

La mejor parte es que, incluso si GMT es un nombre de zona horaria no válida, sigue devolviendo la zona horaria GMT debido al comportamiento predeterminado de getTimeZone.


La respuesta corta es:

  • agregar "default-time-zone = utc" a my.cnf
  • en su código, siempre "piense" en UTC, excepto cuando muestre fechas para sus usuarios
  • al obtener / establecer fechas o marcas de tiempo con JDBC, siempre use el parámetro Calendario, configurado en UTC:

    resultset.getTimestamp ("mi_fecha", Calendar.getInstance (TimeZone.getTimeZone ("UTC")));

  • sincronice sus servidores con NTP o confíe solo en el servidor de la base de datos para decirle qué hora es.

La respuesta larga es esta:

Cuando se trata de fechas y zonas horarias en cualquier base de datos y con cualquier código de cliente, generalmente recomiendo la siguiente política:

  1. Configure su base de datos para usar la zona horaria UTC , en lugar de usar la zona horaria local del servidor (a menos que sea UTC, por supuesto).

    • Cómo hacerlo depende de su servidor de base de datos. Las instrucciones para MySQL se pueden encontrar aquí: http://dev.mysql.com/doc/refman/5.0/en/time-zone-support.html . Básicamente, debes escribir esto en my.cnf: default-time-zone = utc

    • De esta forma, puede alojar sus servidores de bases de datos en cualquier lugar, cambiar fácilmente su ubicación de alojamiento y, en general, manipular las fechas en sus servidores sin ambigüedades.

    • Si realmente prefiere usar una zona horaria local, le recomiendo que al menos apague el horario de verano, porque tener fechas ambiguas en su base de datos puede ser una verdadera pesadilla.
      • Por ejemplo, si está construyendo un servicio de telefonía y está utilizando el horario de verano en su servidor de base de datos, entonces está buscando problemas: no habrá forma de saber si un cliente que llamó desde "2008-10-26 02:30 : 00 "a" 2008-10-26 02:35:00 "en realidad solicitó 5 minutos o durante 1 hora y 5 minutos (¡suponiendo que el horario de verano se produjera el 26 de octubre a las 3 a.m.)!
  2. Dentro de su código de aplicación, siempre use fechas UTC, excepto cuando muestre fechas a sus usuarios.

    • En Java, al leer desde la base de datos, siempre use:

    Timestamp myDate = resultSet.getTimestamp ("mi_fecha", Calendar.getInstance (TimeZone.getTimeZone ("UTC")));

    • Si no lo hace, se supondrá que la marca de tiempo está en su TimeZone local, en lugar de UTC.
  3. Sincronice sus servidores o solo confíe en el tiempo del servidor de la base de datos

    • Si tiene su servidor web en un servidor (o más) y su servidor de base de datos en otro servidor, le recomiendo encarecidamente que sincronice sus relojes con NTP.

    • O bien, solo confíe en un servidor para decirle qué hora es. Por lo general, el servidor de base de datos es el mejor para pedir tiempo. En otras palabras, evite un código como este:

    preparedStatement = connection.prepareStatement ("UPDATE my_table SET my_time =? WHERE [...]");
    java.util.Date now = new java.util.Date (); // ¡hora local! :-(
    preparedStatement.setTimestamp (1, new Timestamp (now.getTime ()));
    int result = preparedStatement.execute ();

    • En cambio, confíe en la hora del servidor de la base de datos:

    preparedStatement = connection.prepareStatement ("UPDATE my_table SET my_time = NOW () DONDE [...]");
    int result = preparedStatement.execute ();

¡Espero que esto ayude! :-)


Una fecha de Java es agnóstica de zona horaria. SIEMPRE representa una fecha en GMD (UTC) en milisegundos desde Epoch.

La ÚNICA vez que una zona horaria es relevante es cuando está emitiendo una fecha como una cadena o analizando una cadena de datos en un objeto de fecha.


MiniQuark dio algunas buenas respuestas para las bases de datos en general, pero hay algunas peculiaridades específicas de MySql a considerar ...

Configure su base de datos para usar la zona horaria UTC

Eso en realidad no será suficiente para solucionar el problema. Si pasa un java.util.Date a MySql como lo estaba haciendo el OP, el controlador MySql cambiará el valor para que se vea como la misma hora local en la zona horaria de la base de datos.

Ejemplo: su base de datos si está configurada para UTC. Su aplicación es EST. Pasas un objeto java.util.Date para las 5:00 (EST). La base de datos lo convertirá a las 5:00 UTC y lo almacenará. Increíble.

Tendría que ajustar el tiempo antes de pasar los datos para "deshacer" este ajuste automático. Algo como...

long originalTime = originalDate.getTime(); Date newDate = new Date(originalTime - TimeZone.getDefault().getOffset(originalTime)); ps.setDate(1, newDate);

Leer los datos nuevamente requiere una conversión similar.

long dbTime = rs.getTimestamp(1).getTime(); Date originalDate = new Date(dbTime + TimeZone.getDefault().getOffset(dbTime));

Aquí hay otra peculiaridad divertida ...

En Java, al leer desde la base de datos, siempre use: Timestamp myDate = resultSet.getTimestamp ("my_date", Calendar.getInstance (TimeZone.getTimeZone ("UTC")));

MySql en realidad ignora ese parámetro de calendario. Esto devuelve el mismo valor independientemente del calendario que lo pase.


Tuve el mismo problema, y ​​me llevó casi un día rastrearlo. Estoy almacenando columnas DateTime en MySQL. La instancia de RDS, que se ejecuta en la nube de Amazon, está configurada correctamente para tener una marca de tiempo UTC de forma predeterminada.

El código de Buggy es:

String startTime = "2013-02-01T04:00:00.000Z"; DateTime dt = ISODateTimeFormat.dateTimeParser().parseDateTime(startTime); PreparedStatement stmt = connection.prepareStatement(insertStatementTemplate); Timestamp ts = new Timestamp(dt.getMillis()); stmt.setTimestamp(1, ts, Calendar.getInstance(TimeZone.getTimeZone("UTC")));

En el código anterior, ¡la llamada ".setTimestamp" NO tomaría la fecha como una fecha UTC!

Después de horas de investigación, esto resulta ser un error conocido en el controlador Java / MySQL. La llamada a setTimestamp solo ignora el parámetro Calendar.

Para solucionar esto, agregue el " useLegacyDatetimeCode = false " a su URI de base de datos.

private final static String DatabaseName = "jdbc:mysql://foo/?useLegacyDatetimeCode=false";

Tan pronto como lo hice, la fecha almacenada en la base de datos MySQL estaba en forma UTC adecuada, en lugar de en la zona horaria de mi estación de trabajo local.