¿Debo usar el tipo de datos de fecha y hora o marca de tiempo en MySQL?

¿Recomendaría utilizar un datetime o con una fecha y hora campo, y por qué (usando MySQL)?

Estoy trabajando con PHP en el lado del servidor.

preguntado el 03 de enero de 09 a las 14:01

esto tiene alguna información relevante codeproject.com/Tips/1215635/MySQL-DATETIME-vs-TIMESTAMP -

Si desea que su aplicación se rompa en febrero, use la marca de tiempo en 2038. Verifique el rango de fechas. -

Si existe la más mínima posibilidad de que su base de datos necesite almacenar valores en una zona horaria diferente o recibir conexiones desde una aplicación en una zona horaria diferente, considere usar los CHAR ISO-8601 para todas sus marcas de tiempo importantes. Vea esta pregunta: stackoverflow.com/questions/40670532/… -

30 Respuestas

Las marcas de tiempo en MySQL se utilizan generalmente para realizar un seguimiento de los cambios en los registros y, a menudo, se actualizan cada vez que se cambia el registro. Si desea almacenar un valor específico, debe usar un campo de fecha y hora.

Si quería decir que desea decidir entre usar una marca de tiempo de UNIX o un campo de fecha y hora nativo de MySQL, elija el formato nativo. Puede hacer cálculos dentro de MySQL de esa manera ("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)") y es simple cambiar el formato del valor a una marca de tiempo UNIX ("SELECT UNIX_TIMESTAMP(my_datetime)") cuando consulta el registro si desea operar en él con PHP.

Respondido 24 Feb 18, 04:02

Una diferencia importante es que DATETIME representa una fecha (como se encuentra en un calendario) y una hora (como se puede observar en un reloj de pared), mientras que TIMESTAMP representa un momento bien definido. Esto podría ser muy importante si su aplicación maneja zonas horarias. ¿Hace cuánto fue '2010-09-01 16:31:00'? Depende de la zona horaria en la que te encuentres. Para mí fue hace unos segundos, para ti puede representar un momento en el futuro. Si digo 1283351460 segundos desde '1970-01-01 00:00:00 UTC', sabes exactamente de qué momento hablo. (Vea la excelente respuesta de Nir a continuación). [Desventaja: rango válido]. - MattBianco

Otra diferencia: las consultas con fecha y hora "nativa" no se almacenarán en caché, pero las consultas con marca de tiempo sí. - ONZ_

"Las marcas de tiempo en MySQL generalmente se usan para rastrear cambios en los registros" No creo que esa sea una buena respuesta. Las marcas de tiempo son mucho más poderosas y complicadas que eso, como dijeron MattBianco y Nir. Aunque, la segunda parte de la respuesta es muy buena. Es cierto lo que dijo blivet y es un buen consejo. - santiagobasulto

En MySQL 5 y superior, TIMESTAMP los valores se convierten de la zona horaria actual a UTC para su almacenamiento y se vuelven a convertir de UTC a la zona horaria actual para su recuperación. (Esto ocurre solo para el tipo de datos TIMESTAMP, y no para otros tipos como DATETIME.)

De forma predeterminada, la zona horaria actual para cada conexión es la hora del servidor. La zona horaria se puede configurar por conexión, como se describe en Compatibilidad con la zona horaria del servidor MySQL.

Respondido 05 Oct 15, 18:10

esta presentación de OReilly es muy buena para este tema (PDF lo siento) cdn.oreillystatic.com/en/assets/1/event/36/… - gcb

También se trata de la naturaleza del evento: - Una videoconferencia (TIMESTAMP). Todos los asistentes deben ver una referencia a un instante de tiempo absoluto ajustado a su zona horaria. - Una hora de tarea local (DATETIME), debo hacer esta tarea el 2014/03/31 a las 9:00 a.m. No importa si ese día estoy trabajando en Nueva York o París. Comenzaré a trabajar a las 8:00 a.m. de la hora local del lugar donde estaré ese día. - Yucer

Siempre uso los campos DATETIME para cualquier cosa que no sean metadatos de fila (fecha de creación o modificación).

As mencionado en la documentación de MySQL:

El tipo DATETIME se utiliza cuando necesita valores que contienen información de fecha y hora. MySQL recupera y muestra los valores DATETIME en formato 'AAAA-MM-DD HH: MM: SS'. El rango admitido es '1000-01-01 00:00:00' a '9999-12-31 23:59:59'.

...

El tipo de datos TIMESTAMP tiene un rango de '1970-01-01 00:00:01' UTC a '2038-01-09 03:14:07' UTC. Tiene diferentes propiedades, según la versión de MySQL y el modo SQL en el que se ejecuta el servidor.

Es muy probable que alcance el límite inferior de TIMESTAMP en el uso general, por ejemplo, almacenando la fecha de nacimiento.

Respondido 10 ago 12, 15:08

también puedes golpear el superior limite fácilmente si está en la banca o en el sector inmobiliario ... las hipotecas a 30 años van más allá de 2038 ahora - Kip

Por supuesto, use marcas de tiempo Unix de 64 bits. Por ejemplo, en Java, new Date().getTime() ya le da un valor de 64 bits. - sergey orshansky

Ni idea. Es un problema mucho mayor que solo MySQL y no hay una solución simple: en.wikipedia.org/wiki/Year_2038_problem No creo que MySQL pueda simplemente declarar que las marcas de tiempo ahora son de 64 bits y asumir que todo estará bien. No controlan el hardware. - escrónido

Los siguientes ejemplos muestran cómo TIMESTAMP el tipo de fecha cambió los valores después de cambiar el time-zone to 'america/new_york' sin que importe DATETIMEno ha cambiado.

mysql> show variables like '%time_zone%';
+------------------+---------------------+
| Variable_name    | Value               |
+------------------+---------------------+
| system_time_zone | India Standard Time |
| time_zone        | Asia/Calcutta       |
+------------------+---------------------+

mysql> create table datedemo(
    -> mydatetime datetime,
    -> mytimestamp timestamp
    -> );

mysql> insert into datedemo values ((now()),(now()));

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 14:11:09 |
+---------------------+---------------------+

mysql> set time_zone="america/new_york";

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 04:41:09 |
+---------------------+---------------------+

Convertí mi respuesta en un artículo para que más personas puedan encontrar esto útil, MySQL: tipos de datos de fecha y hora frente a marca de tiempo.

Respondido 05 Oct 15, 18:10

Bueno, en realidad el DATETIME la hora efectiva cambió con el cambio de zona horaria, TIMESTAMP no cambió, pero la representación humana sí. - Flindeberg

La principal diferencia es que DATETIME es constante, mientras que TIMESTAMP se ve afectado por el time_zone ajuste.

Por lo tanto, solo importa cuándo tiene, o puede que en el futuro lo haya hecho, clústeres sincronizados entre zonas horarias.

En palabras más simples: Si tengo una base de datos en Australia y tomo un volcado de esa base de datos para sincronizar / poblar una base de datos en Estados Unidos, entonces TIMESTAMP se actualizaría para reflejar el tiempo real del evento en la nueva zona horaria, mientras que DATETIME aún reflejaría la hora del evento en la zona horaria de au.

Un gran ejemplo del uso de DATETIME donde se debería haber usado TIMESTAMP es en Facebook, donde sus servidores nunca están seguros de a qué hora sucedieron las cosas en las distintas zonas horarias. Una vez tuve una conversación en la que el tiempo decía que estaba respondiendo mensajes antes de que el mensaje fuera enviado. (Esto, por supuesto, también podría haber sido causado por una mala traducción de la zona horaria en el software de mensajería si las horas se publicaron en lugar de sincronizar).

Respondido el 03 de enero de 13 a las 11:01

No creo que esta sea una buena forma de pensar. Solo almacenaría y procesaría todas las fechas en UTC y me aseguraría de que el front-end las muestre de acuerdo con la zona horaria dada. Este enfoque es simple y predecible. - Kos

@Kos: ¿no está almacenando y procesando todas las fechas en UTC exactamente lo que TIMESTAMP está haciendo internamente? (¿Entonces convertirlo para mostrar su zona horaria local?) - carbocatión

my zona horaria local? ¿Cómo sabría su DB mi zona horaria? ;-) Normalmente hay bastante procesamiento entre la base de datos y la interfaz de usuario. Hago la localización solo después de todo el procesamiento. - Kos

@Koz: mi base de datos no conoce la zona horaria de su base de datos:! Pero sí conoce la marca de tiempo. Su base de datos conoce su propia configuración de zona horaria y la aplica al interpretar / representar la marca de tiempo. 1:01 am del 11 de diciembre de 2013 en Beijing China no es el mismo momento que la 1:01 am del 11 de diciembre de 2013 en Sydney, Australia. Google: 'zonas horarias' y 'primer meridiano'. - ekerner

Tomo esta decisión sobre una base semántica.

Utilizo una marca de tiempo cuando necesito registrar un punto (más o menos) fijo en el tiempo. Por ejemplo, cuando se insertó un registro en la base de datos o cuando tuvo lugar alguna acción del usuario.

Utilizo un campo de fecha y hora cuando la fecha / hora se puede establecer y cambiar arbitrariamente. Por ejemplo, cuando un usuario puede guardar cambios posteriores de citas.

Respondido el 14 de enero de 11 a las 16:01

marca de tiempo: punto fijo en el tiempo, hora universal coordinada fecha y hora: relativo a un punto de vista, a una referencia de tiempo (ej. zona horaria hora local), podría ser .. ¿Hora local coordinada? - Yucer

Recomiendo el uso de ninguno un campo DATETIME o TIMESTAMP. Si desea representar un día específico como un todo (como un cumpleaños), use un tipo de FECHA, pero si está siendo más específico que eso, probablemente esté interesado en registrar un momento real en lugar de una unidad de hora (día, semana, mes, año). En lugar de usar DATETIME o TIMESTAMP, use un BIGINT y simplemente almacene el número de milisegundos desde la época (System.currentTimeMillis () si está usando Java). Esto tiene varias ventajas:

  1. Evita el bloqueo del proveedor. Prácticamente todas las bases de datos admiten números enteros de manera relativamente similar. Suponga que desea trasladarse a otra base de datos. ¿Quiere preocuparse por las diferencias entre los valores DATETIME de MySQL y cómo los define Oracle? Incluso entre las diferentes versiones de MySQL, TIMESTAMPS tienen un nivel diferente de precisión. Recientemente, MySQL admitió milisegundos en las marcas de tiempo.
  2. Sin problemas de zona horaria. Aquí ha habido algunos comentarios interesantes sobre lo que sucede con las zonas horarias con los diferentes tipos de datos. Pero, ¿es esto de conocimiento común y sus compañeros de trabajo se tomarán el tiempo para aprenderlo? Por otro lado, es bastante difícil equivocarse al cambiar un BigINT a un java.util.Date. El uso de BIGINT hace que muchos problemas con las zonas horarias se queden en el camino.
  3. No se preocupe por los rangos o la precisión. No tiene que preocuparse por lo que se verá interrumpido por rangos de fechas futuros (TIMESTAMP solo llega hasta 2038).
  4. Integración de herramientas de terceros. Al usar un número entero, es trivial que las herramientas de terceros (por ejemplo, EclipseLink) interactúen con la base de datos. No todas las herramientas de terceros van a tener la misma comprensión de una "fecha y hora" que MySQL. ¿Quiere probar y averiguar en Hibernate si debe usar un objeto java.sql.TimeStamp o java.util.Date si está usando estos tipos de datos personalizados? El uso de sus tipos de datos base hace que el uso de herramientas de terceros sea trivial.

Este problema está estrechamente relacionado con cómo debe almacenar un valor monetario (es decir, $ 1.99) en una base de datos. ¿Debería utilizar un decimal, o el tipo de dinero de la base de datos, o lo peor de todo un doble? Las 3 de estas opciones son terribles, por muchas de las mismas razones enumeradas anteriormente. La solución es almacenar el valor del dinero en centavos usando BIGINT y luego convertir los centavos a dólares cuando muestra el valor al usuario. El trabajo de la base de datos es almacenar datos y NO interpretarlos. Todos estos tipos de datos sofisticados que ve en las bases de datos (especialmente Oracle) agregan poco y lo llevan al camino hacia el bloqueo del proveedor.

Respondido el 13 de diciembre de 17 a las 00:12

Me gusta esta solucion. TIMESTAMP que expira en 2038 es un problema importante. ¡Eso no está tan lejos! - Charlie Dalsass

@CharlieDalsass ¿Crees que el software actual estará allí en ese momento :-P - Habeb Perwad

Hace que sea difícil consultar datos por fecha si se almacenan como una cantidad de milisegundos: Ali Said

Esta es realmente la mejor solución si le importa la portabilidad y el manejo de usuarios en múltiples zonas horarias, o bases de datos en diferentes zonas horarias que los usuarios. TIMESTAMP podría ser el camino a seguir si no tiene fallas de diseño. Lástima que las soluciones rotas obtuvieron más votos porque se publicaron temprano (¡años!). - Alemán

Excelente solucion! Y tienes toda la razón sobre estar "encerrado". Cuando adquiere el hábito de dejar que otros "hagan el trabajo por usted", entonces comienza a perder las partes que hacen que USTED sea el programador. - fmc

  1. TIMESTAMP es de cuatro bytes frente a ocho bytes para DATETIME.

  2. Las marcas de tiempo también son más claras en la base de datos y se indexan más rápido.

  3. El tipo DATETIME se utiliza cuando necesita valores que contienen información de fecha y hora. MySQL recupera y muestra los valores DATETIME en formato 'AAAA-MM-DD HH: MM: SS'. El rango admitido es '1000-01-01 00:00:00 ′ a' 9999-12-31 23:59:59 ′.

El tipo de datos TIMESTAMP tiene un rango de '1970-01-01 00:00:01 ′ UTC a' 2038-01-09 03:14:07 ′ UTC. Tiene diferentes propiedades, según la versión de MySQL y el modo SQL en el que se ejecuta el servidor.

  1. DATETIME es constante, mientras que TIMESTAMP se ve afectado por la configuración de time_zone.

Respondido 05 Oct 15, 18:10

Debe aclarar el n. ° 4: la marca de tiempo almacenada es constante y no relativa (completamente agnóstica) a la zona horaria, mientras que la salida mostrada en la recuperación se ve afectada por la zona horaria de la sesión solicitante. DATETIME siempre es relativo a la zona horaria en la que se registró, y siempre debe considerarse en ese contexto, una responsabilidad que ahora recae en la aplicación. - christopher mcgowan

Gran respuesta. Para agregar a esta respuesta, si intentamos almacenar valores más allá de '2038-01-09 03:14:07', obtenemos un error o se almacena como '0000-00-00 00:00:00'. Recibí este error para mi base de datos, ya que tiene valores diferidos (para fines de cifrado). - KarthikS

Además, hay un problema con DATETIME con el valor DEFAULT en versiones de mysql por debajo de 5.5. dba.stackexchange.com/questions/132951/… - Velaro

TIMESTAMP es de 4 bytes frente a 8 bytes para DATETIME.

http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html

Pero como dijo Scronide, tiene un límite inferior del año 1970. Sin embargo, es genial para cualquier cosa que pueda suceder en el futuro;)

Respondido el 04 de enero de 09 a las 09:01

El futuro termina a las 2038-01-19 03:14:07 UTC. - MattBianco

Eso es estúpido. Pensé que el tipo TIMESTAMP estaría "preparado para el futuro" porque es relativamente nuevo. No puede molestarse en convertir la fecha y hora a UTC y viceversa cada vez que trabaja con diferentes zonas horarias. Deberían haber hecho más grande TIMESTAMP ... al menos 1 byte más grande. agregará 68 * 255 = 17340 años más ... aunque no estará alineado en 32 bits. - NickSoft

¿Sabes por qué TIMESTAMP termina en 2038? Porque es un número entero, y los números enteros tienen un límite que es 2147483647. Creo que esta es la razón. Puede ser que si cambian su tipo a varchar y cambian la forma de manipularlo, estará "preparado para el futuro". - VINSA

@vinsa, no creo que esté listo para el futuro para entonces. ¿Todavía recuerdas el error Y2K? Se acerca el 2038. - marcapasos

Para 2038, MySQL (si todavía existe) simplemente actualizará el campo TIMESTAMP para usar más de 4 bytes y permitir un rango más amplio - Las nueces

Depende de la aplicación, de verdad.

Considere establecer una marca de tiempo por parte de un usuario en un servidor en Nueva York, para una cita en Sanghai. Ahora, cuando el usuario se conecta en Sanghai, accede a la misma marca de tiempo de la cita desde un servidor reflejado en Tokio. Verá la cita en la hora de Tokio, compensada con la hora original de Nueva York.

Entonces, para valores que representan el tiempo del usuario, como una cita o un horario, la fecha y hora es mejor. Permite al usuario controlar la fecha y hora exacta deseada, independientemente de la configuración del servidor. La hora establecida es la hora establecida, no se ve afectada por la zona horaria del servidor, la zona horaria del usuario o por los cambios en la forma en que se calcula el horario de verano (sí, cambia).

Por otro lado, para los valores que representan la hora del sistema, como las transacciones de pago, las modificaciones de la tabla o el registro, utilice siempre marcas de tiempo. El sistema no se verá afectado al mover el servidor a otra zona horaria o al comparar servidores en diferentes zonas horarias.

Las marcas de tiempo también son más claras en la base de datos y se indexan más rápido.

Respondido 26 Oct 10, 22:10

Su aplicación no debe depender de la zona horaria del servidor. Una aplicación SIEMPRE debe seleccionar la zona horaria en la sesión de la conexión de base de datos que utiliza antes de emitir cualquier consulta. Si una conexión se comparte entre varios usuarios (p. Ej., Webapp), use UTC y realice la conversión de zona horaria en el lado de la representación. - dolmen

2016 +: lo que te aconsejo es configurar tu zona horaria de Mysql en UTC y usar DATETIME:

Cualquier marco de interfaz de usuario reciente (Angular 1/2, react, Vue, ...) puede convertir fácil y automáticamente su fecha y hora UTC a la hora local.

Adicionalmente:

(A menos que sea probable que cambie la zona horaria de sus servidores)


Ejemplo con AngularJs

// back-end: format for angular within the sql query
SELECT DATE_FORMAT(my_datetime, "%Y-%m-%dT%TZ")...

// font-end Output the localised time
{{item.my_datetime | date :'medium' }}

Todo el formato de hora localizado disponible aquí: https://docs.angularjs.org/api/ng/filter/date

Respondido 26 ago 17, 15:08

Sus datos no deben adjuntarse a la configuración de la zona horaria de sus servidores. Tal vez, funcione para usted si tiene una sola caja MySql debajo de su escritorio - Jin

@Jin UTC significa que no hay zona horaria como TIMESTAMP. Si todos sus servidores están en UTC, no hay problemas. Tal vez no funcione para usted si tiene una configuración de 2000. - sebastien horin

TIMESTAMP puede actualizarse a un valor de 64 bits en el futuro. Entonces no hay más problema. - Twicejr

Cargar bibliotecas completas de terceros para capturar algo como esto tampoco puede ser tan bueno para el rendimiento, ¿verdad? Dado que es del lado del cliente y no afecta su base de datos ... Aún así, cualquier cosa que haga en el front-end requerirá verificaciones en el servidor. Entonces, pensando en el completar imagen, ¿realmente ayuda con el problema de la velocidad? - Por cierto, creo que esos puntos de referencia son un poco extraños. Usar una cadena en una consulta para comparar campos de marca de tiempo también se siente bastante extraño. Eso también debe dañar el rendimiento, ¿verdad? - NoobishPro

No confíe en su aplicación en la zona horaria del servidor. En su lugar, defina la zona horaria que se utilizará en cada conexión de base de datos: SET time_zone = '+0:00'; para UTC. - dolmen

TIMESTAMP siempre está en UTC (es decir, segundos transcurridos desde 1970-01-01, en UTC), y su servidor MySQL lo convierte automáticamente a la fecha / hora de la zona horaria de la conexión. A largo plazo, TIMESTAMP es el camino a seguir porque sabe que sus datos temporales siempre estarán en UTC. Por ejemplo, no arruinará sus fechas si migra a un servidor diferente o si cambia la configuración de la zona horaria en su servidor.

Nota: la zona horaria de conexión predeterminada es la zona horaria del servidor, pero esto puede (debería) cambiarse por sesión (consulte SET time_zone = ...).

contestado el 21 de mayo de 19 a las 17:05

A timestamp campo es un caso especial del datetime campo. Puedes crear timestamp columnas para tener propiedades especiales; se puede configurar para que se actualice a sí mismo al crear y / o actualizar.

En términos de bases de datos "más grandes", timestamp tiene un par de activadores de casos especiales.

Cuál es el correcto depende completamente de lo que quieras hacer.

Respondido 03 Jul 16, 19:07

No, la diferencia no es solo "un caso especial". Porque las zonas horarias de la sesión que establece / consulta los valores están involucradas de manera diferente. - dolmen

Me alegra que hayas puesto "Lo que es correcto depende completamente de lo que quieras hacer". Hay demasiadas respuestas en SE que dicen, sin justificación suficiente, "Debe nunca hacer X "o" Debes siempre haz Y ". - Ladrón de martillos Agi

Comparación entre DATETIME, TIMESTAMP y DATE

enter image description here

¿Qué es esa [.fracción]?

  • Un valor DATETIME o TIMESTAMP puede incluir una fracción de segundos finales con una precisión de hasta microsegundos (6 dígitos). En particular, cualquier parte fraccionaria de un valor insertado en una columna DATETIME o TIMESTAMP se almacena en lugar de descartarse. Por supuesto, esto es opcional.

Fuentes:

Respondido 16 ago 17, 07:08

Vale la pena señalar que en MySQL puede usar algo similar a lo siguiente al crear las columnas de su tabla:

on update CURRENT_TIMESTAMP

Esto actualizará la hora en cada instancia que modifique una fila y, a veces, es muy útil para la información almacenada de la última edición. Esto solo funciona con la marca de tiempo, no con la fecha y hora.

Respondido 05 Oct 15, 18:10

Siempre usaría una marca de tiempo de Unix cuando trabaje con MySQL y PHP. La razón principal de que esto sea el valor predeterminado datos El método en PHP usa una marca de tiempo como parámetro, por lo que no sería necesario analizarlo.

Para obtener la marca de tiempo actual de Unix en PHP, simplemente haga time();
y en MySQL hacer SELECT UNIX_TIMESTAMP();.

Respondido 14 ago 20, 18:08

-1 De hecho, creo que la respuesta a continuación es mejor: el uso de datetime le permite introducir más lógica para el procesamiento de fechas en MySQL, lo que puede ser muy útil. - toby hede

¿No ha habido pruebas de rendimiento que muestren que la ordenación en MySQL es más lenta que en php? - sdkfasldf

bueno depende, a veces es bueno usarlo cuando nos gusta no usar strtotime. (php5.3 dep) - Adam Ramadán

puede insertar la lógica en mysql simplemente usando FROM_UNIXTIME si es necesario - inarilo

Solía ​​usar todas las marcas de tiempo de Unix en mis aplicaciones PHP y en MySQL, sin embargo, descubrí que es mucho más conveniente almacenar fechas y horas en MySQL como tipos de fecha / hora nativos. Esto es especialmente útil para fines de informes y solo para explorar conjuntos de datos. Con el tiempo, a medida que me frustraba tener que copiar / pasar las marcas de tiempo de Unix, comencé a cambiar. Estoy bastante seguro de que hay rendimiento y otros pros / contras, pero dependiendo de su caso de uso, la conveniencia puede ser más importante que las microoptimizaciones. - davidscherer

Ninguno de los dos. La DATETIME y TIMESTAMP los tipos están fundamentalmente rotos para casos de uso genéricos. MySQL los cambiará en el futuro. Deberías usar BIGINT y marcas de tiempo de UNIX a menos que tenga una razón específica para usar otra cosa.

Casos especiales

Aquí hay algunas situaciones específicas en las que su elección es más fácil y no necesita el análisis y la recomendación general en esta respuesta.

  • Solo fecha - si solo le importa la fecha (como la fecha del próximo Año Nuevo Lunar, 2020-02-25) Y tiene una idea clara de la zona horaria que aplica esa fecha (o no le importa, como en el caso de Lunar Año Nuevo) luego use el DATE tipo de columna.

  • Registrar tiempos de inserción - si está registrando las fechas / horas de inserción para las filas en su base de datos Y no le importa que su aplicación se romperá en los próximos 19 años, luego continúe y use TIMESTAMP con un valor predeterminado de CURRENT_TIMESTAMP().

¿Por qué es TIMESTAMP ¿roto?

La TIMESTAMP El tipo se almacena en el disco en la zona horaria UTC. Esto significa que si mueve físicamente su servidor, no se rompe. Eso es bueno ✅. Pero las marcas de tiempo tal como se definen actualmente dejarán de funcionar por completo en el año 2038 ❌.

Cada vez que usted INSERT INTO or SELECT FROM a TIMESTAMP columna, se tiene en cuenta la ubicación física (es decir, la configuración de la zona horaria) de su cliente / servidor de aplicaciones. Si mueve su servidor de aplicaciones, sus fechas se romperán ❌.

¿Por qué es DATETIME ¿roto?

A DATETIME almacena un DATE y TIME en la misma columna. Ninguna de estas cosas tiene ningún significado a menos que se comprenda la zona horaria y la zona horaria no se almacene en ningún lugar ❌. Debe poner la zona horaria deseada como comentario en la columna porque la zona horaria está indisolublemente vinculada a los datos. Muy pocas personas usan comentarios de columna, por lo tanto, este es un error que está esperando a suceder. Heredé un servidor de Arizona, por lo que siempre necesito convertir todas las marcas de tiempo DESDE la hora de Arizona y luego A otra hora.

La única situación es DATETIME es correcto es completar esta oración:

Su año 2020 solar nuevo año comienza exactamente en DATETIME("2020-01-01 00:00:00").

No hay otro buen uso para DATETIMEs. Quizás se imagina un servidor web para el gobierno de una ciudad en Delaware. Seguramente se puede implicar que la zona horaria de este servidor y todas las personas que acceden a este servidor están en Delaware, con la zona horaria del este, ¿verdad? ¡Equivocado! En este milenio, todos pensamos que los servidores existen en "la nube". Por lo tanto, siempre es incorrecto pensar en su servidor en una zona horaria específica, porque su servidor se moverá algún día.

Nota: MySQL ahora admite compensaciones de zona horaria in DATETIME literalesgracias @Marko). Esto puede hacer que la inserción DATETIMEEs más conveniente para usted pero no aborda el significado incompleto y por lo tanto inútil de los datos, este problema fatal identifica ("❌") arriba.

¿Cómo se utiliza? BIGINT?

Definir:

CREATE TEMPORARY TABLE good_times (
    a_time BIGINT
)

Inserte un valor específico:

INSERT INTO good_times VALUES (
    UNIX_TIMESTAMP(CONVERT_TZ("2014-12-03 12:24:54", '+00:00', @@global.time_zone))
);

O, por supuesto, esto es mucho mejor desde su aplicación, como:

$statement = $myDB->prepare('INSERT INTO good_times VALUES (?)');
$statement->execute([$someTime->getTimestamp()]);

Seleccione:

SELECT a_time FROM good_times;

Existen técnicas para filtrar tiempos relativos (seleccione publicaciones dentro de los últimos 30 días, encuentre usuarios que compraron dentro de los 10 minutos posteriores al registro) más allá del alcance aquí.

Respondido el 06 de Septiembre de 20 a las 17:09

Su punto de que DATETIME no tiene significado a menos que se entienda la zona horaria no lo rompe. El código de su aplicación debe convertir el valor de fecha y hora en la zona horaria deseada antes de insertarlo en la base de datos, por lo que, al recuperar el valor de la base de datos, sabrá en qué zona horaria se encuentra. Incluso eso es innecesario si su aplicación no se preocupa por la zona horaria, que sería el caso cuando todos los usuarios de la aplicación se encuentran dentro de la misma zona horaria (por ejemplo, la aplicación se usa solo en Francia). - Marko

@Marko ese argumento se aplica igualmente bien para almacenar valores de fecha y hora en una base de datos como un VARCHAR: el código de su aplicación debe convertir el valor al formato deseado antes de que se inserte en la base de datos. Mi opinión es que las bases de datos están hechas para almacenar datos, incluido todo el contexto necesario para que esos datos tengan significado. - Guillermo Entriken

no, no se aplica igualmente bien porque no puede manipular los valores VARCHAR utilizando funciones de fecha integradas en la base de datos y operadores de comparación de fechas - Marko

Aquí hay una función incorporada de MySQL que se aplica a un ISO 8601 VARCHAR valor: SELECT DATE_ADD("2020-01-01", INTERVAL 2 DAY). Aquí hay un operador de comparación de fechas incorporado de MySQL que aplica ISO 8601 VARCHARs: SELECT "2020-01-01" < "2020-03-01" - Guillermo Entriken

Funciona con la cadena ISO 8601 porque MySQL la reconoce como un literal de fecha e implícitamente lanza el valor VARCHAR a DATE. La diferencia es que almacenar el valor en una columna VARCHAR tomará 10 bytes, mientras que almacenarlo en una columna DATE tomará 3 bytes. También creo que el valor VARCHAR se emitirá implícitamente CADA VEZ que lo use con la función de fecha incorporada o los operadores de comparación de fecha, lo cual está lejos de ser eficiente. Los tipos DATE y DATETIME se implementan por una razón. Además, a partir de MySQL 8.0.19 es posible especificar el desplazamiento de zona horaria con DATETIME. - Marko

Según mi experiencia, si desea un campo de fecha en el que la inserción ocurra solo una vez y no desea tener ninguna actualización o cualquier otra acción en ese campo en particular, vaya con Fecha y hora.

Por ejemplo, considere un user mesa con un FECHA DE REGISTRO campo. En eso user tabla, si desea saber la última hora de inicio de sesión de un usuario en particular, vaya con un campo de fecha y hora escriba para que el campo se actualice.

Si está creando la tabla desde phpMyAdmin la configuración predeterminada actualizará el fecha y hora campo cuando ocurre una actualización de fila. Si su marca de tiempo archivada no se actualiza con la actualización de fila, puede usar la siguiente consulta para hacer una fecha y hora el campo se actualiza automáticamente.

ALTER TABLE your_table
      MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

Respondido 05 Oct 15, 18:10

El tipo de datos de marca de tiempo almacena la fecha y la hora, pero en formato UTC, no en el formato de zona horaria actual como lo hace la fecha y hora. Y cuando recuperas datos, la marca de tiempo vuelve a convertirlos en la hora actual de la zona horaria.

Entonces, suponga que está en EE. UU. Y obtiene datos de un servidor que tiene una zona horaria de EE. UU. Luego obtendrá la fecha y la hora de acuerdo con la zona horaria de EE. UU. La columna de tipo de datos de marca de tiempo siempre se actualiza automáticamente cuando se actualiza su fila. Por lo tanto, puede ser útil realizar un seguimiento de cuándo se actualizó una fila en particular la última vez.

Para obtener más detalles, puede leer la publicación del blog. Marca de tiempo frente a fecha y hora .

Respondido 05 Oct 15, 18:10

Siempre puede (debe) definir la zona horaria a nivel de sesión con SET time_zone = '+0:00'; (UTC aquí) para estar seguro de lo que obtiene / establece TIMESTAMP valores y evite depender del valor predeterminado de time_zone del servidor que podría cambiar. - dolmen

Siempre uso una marca de tiempo de Unix, simplemente para mantener la cordura cuando trato con mucha información de fecha y hora, especialmente cuando realizo ajustes para zonas horarias, agregando / restando fechas, y cosas por el estilo. Al comparar marcas de tiempo, esto excluye los factores complicados de la zona horaria y le permite ahorrar recursos en el procesamiento del lado del servidor (ya sea código de aplicación o consultas de base de datos) en el sentido de que utiliza aritmética liviana en lugar de agregar / restar fecha y hora más pesadas funciones.

Otra cosa que vale la pena considerar:

Si está creando una aplicación, nunca sabrá cómo podrían tener que usarse sus datos en el futuro. Si termina teniendo que, digamos, comparar un montón de registros en su conjunto de datos, con, digamos, un montón de elementos de una API de terceros, y digamos, colóquelos en orden cronológico, estará feliz de tener Marcas de tiempo Unix para sus filas. Incluso si decide utilizar marcas de tiempo de MySQL, almacene una marca de tiempo de Unix como seguro.

Respondido 05 Oct 15, 18:10

En mi caso, configuro UTC como zona horaria para todo: el sistema, el servidor de la base de datos, etc. cada vez que puedo. Si mi cliente requiere otra zona horaria, la configuro en la aplicación.

Casi siempre prefiero las marcas de tiempo en lugar de los campos de fecha y hora, porque las marcas de tiempo incluyen la zona horaria implícitamente. Entonces, desde el momento en que los usuarios de diferentes zonas horarias accederán a la aplicación y desea que vean fechas y horas en su zona horaria local, este tipo de campo hace que sea bastante fácil hacerlo que si los datos se hubieran guardado en campos de fecha y hora. .

Como ventaja, en el caso de una migración de la base de datos a un sistema con otra zona horaria, me sentiría más seguro usando marcas de tiempo. Sin mencionar los posibles problemas al calcular las diferencias entre dos momentos con un cambio de tiempo de inmersión en el medio y que necesitan una precisión de 1 hora o menos.

Entonces, para resumir, valoro estas ventajas de la marca de tiempo:

  • listo para usar en aplicaciones internacionales (múltiples zonas horarias)
  • migraciones fáciles entre zonas horarias
  • bastante fácil de calcular las diferencias (solo reste ambas marcas de tiempo)
  • no se preocupe por las fechas dentro / fuera de un período de verano

Por todas estas razones, elijo los campos UTC y de marca de tiempo cuando sea posible. Y evito los dolores de cabeza;)

Respondido 24 Feb 17, 18:02

Los datos de la marca de tiempo serán divertidos para la persona que respalde su aplicación cuando llegue el 20 de enero de 2038. tic, tac, tic, tac - wilson hauck

El tipo de marca de tiempo podría aumentarse un poco y duplicar los valores posibles. - Roger Campanera

Pruebe su teoría para 'aumentar un poco' y vea si puede almacenar con éxito el 1 de febrero de 2038 y recuperarla con MySQL. Veamos la definición de su tabla cuando termine, por favor. Probablemente vas a tener muchos conocidos pasados ​​infelices en febrero de 2038. - wilson hauck

@WilsonHauck De todos modos, tendrá que actualizar la versión de MySQL mucho antes de 2038. Y ese TIMESTAMP extendido será manejado por la migración. Además, pocas aplicaciones además del manejo de hipotecas realmente deben preocuparse por 2038 en este momento. - dolmen

@dolmen muchas herramientas y materiales de calidad profesional tienen una garantía de más de 20 años. Entonces algo como warranties.expires_at hoy no podría ser una marca de tiempo de MySQL. - alex

Referencia extraída de este artículo:

Las principales diferencias:

TIMESTAMP se utiliza para realizar un seguimiento de los cambios en los registros y actualizar cada vez que se cambia el registro. DATETIME se utiliza para almacenar valores específicos y estáticos que no se ven afectados por ningún cambio en los registros.

TIMESTAMP también se ve afectado por diferentes ajustes relacionados con la ZONA HORARIA. DATETIME es constante.

TIMESTAMP convirtió internamente la zona horaria actual a UTC para su almacenamiento y, durante la recuperación, volvió a convertirla a la zona horaria actual. DATETIME no puede hacer esto.

Rango admitido de TIMESTAMP: '1970-01-01 00:00:01 ′ UTC a' 2038-01-19 03:14:07 ′ UTC Rango admitido de DATETIME: '1000-01-01 00:00:00 ′ a' 9999 -12-31 23:59:59 ′

Respondido 07 Feb 16, 12:02

Tenga cuidado con el cambio de marca de tiempo cuando realiza una instrucción UPDATE en una tabla. Si tiene una tabla con las columnas 'Name' (varchar), 'Age' (int) y 'Date_Added' (marca de tiempo) y ejecuta la siguiente instrucción DML

UPDATE table
SET age = 30

luego, cada valor en su columna 'Date_Added' se cambiará a la marca de tiempo actual.

Respondido 05 Oct 15, 18:10

en función de cómo configure su mesa, puede controlar este comportamiento. mirar dev.mysql.com/doc/refman/5.5/en/timestamp-initialization.html - Carlos Faiga

@CharlesFaiga El comportamiento predeterminado es que la marca de tiempo se actualice cuando se actualiza cualquier otra columna. Debe desactivar esto explícitamente si desea que la marca de tiempo conserve su valor original: Lloyd Banks

Qué es eso ?! debe establecer la columna de marca de tiempo en ON UPDATE CURRENT_TIMESTAMP - Contador م

Esto es una característica que debe habilitar explícitamente al crear la tabla. - dolmen

+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
|                                       TIMESTAMP                                       |                                 DATETIME                                 |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| TIMESTAMP requires 4 bytes.                                                           | DATETIME requires 8 bytes.                                               |
| Timestamp is the number of seconds that have elapsed since January 1, 1970 00:00 UTC. | DATETIME is a text displays 'YYYY-MM-DD HH:MM:SS' format.                |
| TIMESTAMP supported range: ‘1970-01-01 00:00:01′ UTC to ‘2038-01-19 03:14:07′ UTC.    | DATETIME supported range: ‘1000-01-01 00:00:00′ to ‘9999-12-31 23:59:59′ |
| TIMESTAMP during retrieval converted back to the current time zone.                   | DATETIME can not do this.                                                |
| TIMESTAMP is used mostly for metadata i.e. row created/modified and audit purpose.    | DATETIME is used mostly for user-data.                                   |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+

Respondido 12 Abr '18, 04:04

Encontré una utilidad insuperable en la capacidad de TIMESTAMP para actualizarse automáticamente en función de la hora actual sin el uso de activadores innecesarios. Sin embargo, ese soy solo yo, aunque TIMESTAMP es UTC como se dijo.

Puede realizar un seguimiento en diferentes zonas horarias, por lo que si necesita mostrar una hora relativa, por ejemplo, la hora UTC es lo que desea.

Respondido 05 Oct 15, 18:10

La principal diferencia es

  • un INDICE en la marca de tiempo - funciona
  • un ÍNDICE en Datetime - No funciona

mira este publicar para ver problemas con la indexación de fecha y hora

contestado el 23 de mayo de 17 a las 13:05

Ambos tienen el mismo problema si selecciona con una función basada en el valor de la columna, y ambos se pueden indexar. - marcus adams

¿El índice funciona con la marca de tiempo y no con la fecha y hora? Sacaste conclusiones erróneas de esas publicaciones. - salman a

Otra diferencia entre la marca de tiempo y la fecha y hora es que en la marca de tiempo no se puede establecer el valor predeterminado en NULL.

Respondido 05 Abr '14, 15:04

Evidentemente, está mal. Aquí hay un ejemplo: CREATE TABLE t2 ( ts1 TIMESTAMP NULL, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); La primera columna puede aceptar un valor NULO. - Ormoz

Dejé de usar datetime en mis aplicaciones después de enfrentar muchos problemas y errores relacionados con las zonas horarias. En mi humilde opinión usando timestamp es mejor que datetime en la mayoría de los casos.

Cuando preguntas qué hora es? y la respuesta es algo así como '2019-02-05 21:18:30', que no está completa, no está definida la respuesta porque le falta otra parte, ¿en qué zona horaria? Washington? Moscú Beijing ?

El uso de fechas y horas sin la zona horaria significa que su aplicación se ocupa de solo 1 zona horaria, sin embargo, las marcas de tiempo le brindan los beneficios de datetime además de la flexibilidad de mostrar el mismo momento exacto en diferentes zonas horarias.

Aquí hay algunos casos de los que te arrepentirás de haber usado datetime y desea que haya almacenado sus datos en marcas de tiempo.

  1. Para la comodidad de sus clientes, desea mostrarles las horas en función de sus zonas horarias preferidas sin hacer que hagan los cálculos y convertir la hora a su zona horaria significativa. todo lo que necesita es cambiar la zona horaria y todo el código de su aplicación será el mismo.(En realidad, siempre debe definir la zona horaria al inicio de la aplicación, o solicitar el procesamiento en el caso de aplicaciones PHP)

    SET time_zone = '+2:00';
    
  2. cambió el país en el que se queda y continúa con su trabajo de mantener los datos mientras los ve en una zona horaria diferente (sin cambiar los datos reales).

  3. acepta datos de diferentes clientes en todo el mundo, cada uno de ellos inserta la hora en su zona horaria.

En Pocas Palabras

datetime = la aplicación admite 1 zona horaria (tanto para insertar como para seleccionar)

timestamp = la aplicación admite cualquier zona horaria (tanto para insertar como para seleccionar)


Esta respuesta es solo para resaltar la flexibilidad y facilidad de las marcas de tiempo cuando se trata de zonas horarias, no cubre ninguna otra diferencia como la tamaño de columna o rango o fracción.

Respondido 05 Feb 19, 19:02

y si hay campos que usan datey otros usos de campo timestamp en una mesa. Creo que causará un nuevo problema porque los datos que se filtran por where no está de acuerdo con los cambios de zona horaria. - Erlang P

@ErlangP En ese caso, su aplicación debería solucionar el problema de la zona horaria en el date columna antes de enviar la consulta. - Contador م

Prefiero usar la marca de tiempo para mantener todo en un formato sin formato común y formatear los datos en código PHP o en su consulta SQL. Hay casos en los que resulta útil en su código mantener todo en segundos.

Respondido el 04 de enero de 09 a las 07:01

A TIMESTAMP requiere 4 bytes, mientras que un DATETIME requiere 8 bytes.

Respondido el 23 de junio de 16 a las 15:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.