¿Debo usar el tipo de datos datetime o timestamp en MySQL?


2685

¿Recomendaría usar un campo de fecha y hora o una marca de tiempo , y por qué (usando MySQL)?

Estoy trabajando con PHP en el lado del servidor.



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

Respuestas:


1829

Las marcas de tiempo en MySQL generalmente se usan para rastrear 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 UNIX o un campo de fecha y hora nativo de MySQL, vaya con 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 operarlo con PHP.


981
Una diferencia importante es que DATETIMErepresenta una fecha (como se encuentra en un calendario) y una hora (como se puede observar en un reloj de pared), mientras que TIMESTAMPrepresenta un punto en el tiempo 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 solo 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. (Ver la excelente respuesta de Nir a continuación). [Desventaja: rango válido].
MattBianco

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

39
"Las marcas de tiempo en MySQL generalmente se utilizan para rastrear los cambios en los registros" No creo que sea una buena respuesta. La marca de tiempo es mucho más poderosa y complicada 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

10
También una nota importante, DATETIME y TIMESTAMP pueden usar CURRENT_TIMESTAMP, NOW () respetuosamente como su valor predeterminado, pero DATE por ejemplo no puede, porque usa '0000-00-00' por defecto, así que para resolver ese asunto, U debería escribir Su propio disparador a esa tabla, para insertar la fecha actual (sin hora) en el campo / col con DATE mysql type.
Arthur Kushman

14
@DavidHarkness: Documentación dice "Para especificar las propiedades automáticas, utilice el valor predeterminado CURRENT_TIMESTAMP y ON UPDATE CURRENT_TIMESTAMP cláusulas" dev.mysql.com/doc/refman/5.0/en/timestamp-initialization.html
PLAP

916

En MySQL 5 y superior, los valores de TIMESTAMP se convierten de la zona horaria actual a UTC para el 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).

Por defecto, la zona horaria actual para cada conexión es la hora del servidor. La zona horaria se puede establecer por conexión, como se describe en Soporte de zona horaria del servidor MySQL .


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

13
También se trata de la naturaleza del evento: - Una videoconferencia (TIMESTAMP). Todos los asistentes deben ver una referencia a un instante absoluto de tiempo ajustado a su zona horaria. - A la hora de la tarea local (DATETIME), debería hacer esta tarea el 31/03/2014 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.
platillo

1
Entonces, si CAMBIO la zona horaria del servidor, entonces el valor de TIMESTAMP seguirá siendo el mismo o ¿también cambiará?
Andrew

3
@ Andrew ya que es UTC, seguirá siendo UTC. Sin embargo, la conversión hacia atrás cambiará a la zona horaria del "nuevo" servidor.
nembleton

@yucer - No recomiendo pensar de esa manera. El uso más constante en una economía global es convertir todas las fechas y horas a UTC para su almacenamiento. Por convención, trate Datetime como un campo UTC. Esto pone la carga en todas las tareas que ingresan fechas y horas para realizar la conversión a UTC, pero es un diseño más limpio a largo plazo. Por supuesto, presente la información al usuario en función de su configuración actual. Si el usuario desea ingresar "09:00 en París", déjelos configurar la hora de París, luego ingrese 09:00. Entonces, cualquiera que esté en Nueva York puede encontrar fácilmente a qué hora necesitan estar despiertos a su hora, para teleconferencias.
ToolmakerSteve

524

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

Como se menciona en la documentación de MySQL:

El tipo DATETIME se usa 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 uso general, por ejemplo, almacenar la fecha de nacimiento.


195
también puede alcanzar el límite superior fácilmente si está en la banca o en bienes raíces ... las hipotecas a 30 años van más allá de 2038 ahora
Kip

16
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.
osa

55
+1 para DATETIME: en nuestro flujo de datos, desde SQL Server de la tienda física para la compra y la factura, transferido a MySQL Server para la tienda virtual en la página web, DATETIME es mejor para la fecha y hora de modificación, ya que este tipo de datos también existe en Transact -SQL. Pero TIMESTAMP significa otra cosa en Transact-SQL, es binario como ROWVERSION, aunque MySQL TIMESTAMP es similar a DateTime. Por lo tanto, evitamos el uso de TIMESTAMP para la compatibilidad de los dos DB.
jacouh

10
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 declarar que las marcas de tiempo ahora son de 64 bits y supongo que todo estará bien. No controlan el hardware.
scronide

55
Una fecha de nacimiento puede ser un DATETIME si conoce la hora de nacimiento, como yo lo sé para la mía.
Kris Craig

322

Los siguientes ejemplos muestran cómo el TIMESTAMPtipo de fecha cambió los valores después de cambiar time-zone to 'america/new_york'dónde no DATETIMEse modifica.

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 |
+---------------------+---------------------+

He convertido mi respuesta en un artículo para que más personas puedan encontrar esto útil, MySQL: Tipos de datos de fecha y hora y fecha y hora .


55
Bueno, en realidad el DATETIMEtiempo efectivo cambió con el cambio de zona horaria, TIMESTAMPno cambió, pero la representación humana sí.
flindeberg

3
Parece que este comando no funciona en MySQL 5.6 set time_zone="america/new_york";
Manjunath Reddy

Aquí está la respuesta para el problema de establecer time_zone. stackoverflow.com/questions/3451847/mysql-timezone-change
Manjunath Reddy

2
De acuerdo con @flindeberg. La marca de tiempo representa la hora correcta, no la fecha y hora, después del cambio de zona horaria
Nitin Bansal

193

La principal diferencia es que DATETIME es constante, mientras que TIMESTAMP se ve afectado por la time_zoneconfiguración.

Por lo tanto, solo es importante cuando tiene, o puede tener en el futuro, clústeres sincronizados en diferentes 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 / llenar una base de datos en América, entonces TIMESTAMP se actualizará para reflejar el tiempo real del evento en la nueva zona horaria, mientras que DATETIME todavía reflejan la hora del evento en la zona horaria au .

Un gran ejemplo de DATETIME utilizado donde TIMESTAMP debería haberse utilizado es en Facebook, donde sus servidores nunca están seguros de qué hora sucedió en las zonas horarias. Una vez que tuve una conversación en la que el tiempo decía que estaba respondiendo a los mensajes antes de que el mensaje se enviara realmente. (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 sincronizarse).


83
No creo que esta sea una buena forma de pensar. Simplemente almacenaba y procesaba todas las fechas en UTC y me aseguraba de que el front-end lo muestre de acuerdo con la zona horaria dada. Este enfoque es simple y predecible.
Kos

8
@Kos: ¿no está almacenando y procesando todas las fechas en UTC exactamente lo que TIMESTAMP está haciendo internamente? (¿Luego convertirlo para mostrar su zona horaria local?)
carbocation

10
mi zona horaria local? ¿Cómo conocerí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

3
@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. La 1:01 am del 11 de diciembre de 2013 en Beijing China no es el mismo momento en el tiempo que la 1:01 am del 11 de diciembre de 2013 en Sydney, Australia. Google: 'zonas horarias' y 'meridiano principal'.
ekerner

2
MySQL convierte los valores de TIMESTAMP de la zona horaria actual a UTC para el almacenamiento, y de regreso de UTC a la zona horaria actual para su recuperación. (Esto no ocurre para otros tipos tales como DATETIME.) Dev.mysql.com/doc/refman/5.5/en/datetime.html
Mahdyfo

125

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

Uso una marca de tiempo cuando necesito grabar un punto fijo en el tiempo (más o menos). 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 configurar y cambiar arbitrariamente. Por ejemplo, cuando un usuario puede guardar citas de cambio posteriores.


marca de tiempo - punto fijo en el tiempo, hora universal coordinada datetime - relativa a un punto de vista, a una referencia de tiempo (ej. zona horaria hora local), podría ser .. ¿Hora local coordinada?
platillo

110

Recomiendo no usar 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 tiempo (día, semana, mes, año). En lugar de usar un 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. Casi todas las bases de datos admiten números enteros de manera relativamente similar. Suponga que quiere pasar a otra base de datos. ¿Desea preocuparse por las diferencias entre los valores DATETIME de MySQL y cómo los define Oracle? Incluso entre diferentes versiones de MySQL, TIMESTAMPS tiene un nivel diferente de precisión. Recientemente, MySQL admitió milisegundos en las marcas de tiempo.
  2. No hay problemas de zona horaria. Aquí ha habido algunos comentarios perspicaces sobre lo que sucede con las zonas horarias con los diferentes tipos de datos. ¿Pero es este conocimiento común, y todos sus compañeros de trabajo se tomarán el tiempo para aprenderlo? Por otro lado, es bastante difícil arruinar el cambio de BigINT a java.util.Date. El uso de un BIGINT provoca que muchos problemas con las zonas horarias se anulen.
  3. No te preocupes por los rangos o la precisión. No tiene que preocuparse por lo que se acortará por intervalos de fechas futuros (TIMESTAMP solo va a 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 tendrán la misma comprensión de una "fecha y hora" que MySQL. ¿Quiere probar y descubrir 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 usar un decimal, o el tipo de dinero de la base de datos, o lo peor de todo, un doble? Las 3 opciones son terribles, por muchas de las mismas razones mencionadas anteriormente. La solución es almacenar el valor del dinero en centavos usando BIGINT, y luego convertir 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 inician en el camino hacia el bloqueo de proveedores.


12
Me gusta esta solución TIMESTAMP que expira en 2038 es un problema importante. ¡Eso no está tan lejos!
Charlie Dalsass

44
@CharlieDalsass ¿Crees que el software actual estará allí esa vez
:-P

13
Hace que sea difícil consultar los datos por fecha si se almacenan como una cantidad de milisegundos
Ali Saeed

44
Esta es realmente la mejor solución si le importa la portabilidad y el manejo de usuarios en varias zonas horarias, o la base 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

44
Excelente solucion! Y tienes toda la razón sobre estar "encerrado". Cuando tienes el hábito de dejar que otros "hagan el trabajo por ti", entonces comienzas a perder las partes que te convierten en el programador.
fmc

98

TIMESTAMP es de 4 bytes Vs 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 para el año 1970. Sin embargo, es genial para cualquier cosa que pueda suceder en el futuro;)


186
El futuro termina en 2038-01-19 03:14:07 UTC.
MattBianco

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

10
¿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

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

2
Para 2038, MySQL (si aún existe) simplemente actualizará el campo TIMESTAMP para usar más de 4 bytes y permitir un rango más amplio
the_nuts

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

  2. Las marcas de tiempo también son más ligeras en la base de datos e indexadas más rápido.

  3. El tipo DATETIME se usa 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 TIMESTAMP se ve afectado por la configuración time_zone.

66
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 visualizada 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 corresponde a la aplicación.
Christopher McGowan

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

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

47

Depende de la aplicación, de verdad.

Considere configurar una marca de tiempo 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 duplicado en Tokio. Verá la cita en la hora de Tokio, compensada de la hora original de Nueva York.

Entonces, para los 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 exactas deseadas, 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í, sí cambia).

Por otro lado, para los valores que representan la hora del sistema, como las transacciones de pago, las modificaciones de tablas 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 entre servidores en diferentes zonas horarias.

Las marcas de tiempo también son más ligeras en la base de datos e indexadas más rápido.


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 se comparte una conexión entre varios usuarios (por ejemplo, webapp), use UTC y realice la conversión de zona horaria en el lado de representación.
dolmen

42

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

Cualquier marco front-end reciente (Angular 1/2, react, Vue, ...) puede convertir fácil y automáticamente su fecha y hora UTC a 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' }}

Todos los formatos de hora localizados disponibles aquí: https://docs.angularjs.org/api/ng/filter/date


8
Sus datos no deben adjuntarse a la configuración de 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 te funcione si tienes 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 detectar 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 ... Sin embargo, cualquier cosa que haga en el front-end requerirá verificaciones en el servidor. Entonces, pensando en la imagen completa , ¿realmente ayuda con el problema de la velocidad? - Por cierto, 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

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

37

Un timestampcampo es un caso especial del datetimecampo. Puede crear timestampcolumnas para tener propiedades especiales; se puede configurar para actualizarse en crear y / o actualizar.

En términos de bases de datos "más grandes", timestamptiene un par de desencadenantes de casos especiales.

Lo que es correcto depende completamente de lo que quieres hacer.


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

Me alegra que digas "Lo que es correcto depende completamente de lo que quieras hacer". Hay demasiadas respuestas en SE ese estado, sin justificación suficiente, "Usted debe no hacer X" o "Usted debe siempre hacer Y".
Agi Hammerthief

37

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 para la zona horaria de 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 (ver SET time_zone = ...).


29

Comparación entre DATETIME, TIMESTAMP y DATE

ingrese la descripción de la imagen aquí

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

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

Fuentes:


24

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

Para obtener la marca de tiempo actual de Unix en PHP, solo hazlo time();
y en MySQL do SELECT UNIX_TIMESTAMP();.


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

¿No ha habido puntos de referencia 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 Ramadhan

puede empujar la lógica a 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, he encontrado 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, cuando 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 micro optimizaciones.
DavidScherer

24

Vale la pena señalar que en MySQL puede usar algo en la línea de abajo al crear las columnas de su tabla:

on update CURRENT_TIMESTAMP

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


17

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

Por ejemplo, considere una usertabla con un campo FECHA DE REGISTRO . En esa usertabla, si desea saber la última hora de inicio de sesión de un usuario en particular, vaya con un campo de tipo de marca de tiempo para que el campo se actualice.

Si está creando la tabla desde phpMyAdmin, la configuración predeterminada actualizará el campo de marca de tiempo cuando ocurra 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 que un campo de marca de tiempo se actualice automáticamente.

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

15

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 datetime. Y cuando obtiene datos, la marca de tiempo nuevamente convierte eso en la hora actual de la zona horaria.

Supongamos 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 rastrear cuándo se actualizó una fila en particular la última vez.

Para obtener más detalles, puede leer la publicación del blog Timestamp Vs Datetime .


Siempre puede (debería) definir la zona horaria en el nivel de sesión con SET time_zone = '+0:00';(UTC aquí) para asegurarse de lo que obtiene / establece a partir de los TIMESTAMPvalores y evitar depender del valor predeterminado de time_zone del servidor que podría cambiar.
dolmen

14

Siempre uso una marca de tiempo de Unix, simplemente para mantener la cordura al tratar con mucha información de fecha y hora, especialmente al realizar ajustes para zonas horarias, sumar / restar fechas, y similares. 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 la base de datos) en el sentido de que utiliza aritmética liviana en lugar de sumar / restar fecha y hora más pesados funciones

Otra cosa que vale la pena considerar:

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


14

En mi caso, configuro UTC como zona horaria para todo: el sistema, el servidor de bases de datos, etc., cada vez que puedo. Si mi cliente requiere otra zona horaria, entonces lo 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 tendrán acceso a la aplicación y desea que vean las fechas y horas en su zona horaria local, este tipo de campo hace que sea bastante fácil hacerlo si los datos se guardan en campos de fecha y hora .

Como un plus, 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. No quiere decir posibles problemas al calcular las diferencias entre dos momentos con un cambio de horario de verano en el medio y que necesita 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 (zona horaria múltiple)
  • migraciones fáciles entre zonas horarias
  • diferencias bastante fáciles de calcular (solo resta ambas marcas de tiempo)
  • no se preocupe por las fechas de entrada / salida de un período de verano

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


los datos de fecha y hora serán divertidos para la persona que respalda su solicitud cuando llegue el 20 de enero de 2038. tic tac tic tic
Wilson Hauck

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

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 haya terminado, por favor. Probablemente va a tener muchos conocidos pasados ​​infelices en febrero de 2038.
Wilson Hauck

1
@WilsonHauck Tendrás que actualizar la versión de MySQL mucho antes de 2038 de todos modos. Y ese TIMESTAMP extendido será manejado por la migración. Además, pocas aplicaciones además de manejar hipotecas realmente necesitan preocuparse por 2038 en este momento.
dolmen

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

13

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

UPDATE table
SET age = 30

entonces cada valor individual en su columna 'Fecha_Agregada' se cambiaría a la marca de tiempo actual.


3
según cómo configure su tabla, puede controlar este comportamiento. mira dev.mysql.com/doc/refman/5.5/en/timestamp-initialization.html
Charles Faiga

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

Que es eso ?! debe configurar la columna de marca de tiempo enON UPDATE CURRENT_TIMESTAMP
Contador م

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

13

Referencia tomada de este artículo:

Las principales diferencias:

TIMESTAMP se utiliza para rastrear 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 el almacenamiento, y durante la recuperación se convirtió de nuevo a la zona horaria actual. DATETIME no puede hacer esto.

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


11
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
|                                       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.                                   |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+

10

Otra diferencia entre Timestamp y Datetime es que en Timestamp no puede establecer el valor predeterminado en NULL.


8
Obviamente 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 NULL.
Ormoz

10

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

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



9

Dejé de usar datetimeen mis aplicaciones después de enfrentar muchos problemas y errores relacionados con las zonas horarias. En mi humilde opinión el uso timestampes mejor que datetimeen la mayoría de los casos .

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

El uso de la fecha y hora sin la zona horaria significa que su aplicación solo maneja 1 zona horaria, sin embargo, las marcas de tiempo le brindan los beneficios datetimey la flexibilidad de mostrar el mismo punto exacto de tiempo en diferentes zonas horarias.

Aquí hay algunos casos que harán que te arrepientas de usar datetimey deseen almacenar tus 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 caso de aplicaciones PHP)

    SET time_zone = '+2:00';
  2. cambiaste el país en el que te hospedas y continúas tu trabajo de mantener los datos mientras los ves en una zona horaria diferente (sin cambiar los datos reales).

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

En breve

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 la facilidad de las marcas de tiempo cuando se trata de zonas horarias, no cubre ninguna otra diferencia como el tamaño de la columna, el rango o la fracción .


¿Qué pasa si hay campos que usan datey otros campos usan timestampen una tabla? Creo que causará un nuevo problema porque los datos que se filtran whereno están de acuerdo con los cambios de la zona horaria.
Erlang P

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

7

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 para mantener todo en segundos.



6

Me gusta una marca de tiempo de Unix, porque puedes convertir a números y solo preocuparte por el número. Además, suma / resta y obtiene duraciones, etc. Luego convierte el resultado a Fecha en cualquier formato. Este código descubre cuánto tiempo en minutos pasó entre una marca de tiempo de un documento y la hora actual.

$date  = $item['pubdate']; (etc ...)
$unix_now = time();
$result = strtotime($date, $unix_now);
$unix_diff_min = (($unix_now  - $result) / 60);
$min = round($unix_diff_min);

44
O bien, use una fecha y hora MySQL nativa y legible para humanos, y use funciones MySQL nativas para agregar / restar fechas y horas.
Julien Palard
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.