Answers:
MySQL中的时间戳通常用于跟踪记录的更改,并且通常在每次更改记录时进行更新。如果要存储特定值,则应使用datetime字段。
如果您要决定是使用UNIX时间戳还是使用本机MySQL datetime字段,请采用本机格式。您可以通过这种方式在MySQL中进行计算,
("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)")
并且("SELECT UNIX_TIMESTAMP(my_datetime)")
如果要使用PHP对记录进行查询,则可以很容易地将值的格式更改为UNIX时间戳。
DATETIME
代表一个日期(在日历中可以找到)和一个时间(可以在挂钟上看到),而TIMESTAMP
代表一个明确定义的时间点。如果您的应用程序处理时区,那么这可能非常重要。多久以前是'2010-09-01 16:31:00'?这取决于您所处的时区。对我来说,这只是几秒钟前,对您来说,它可能代表将来的时间。如果我说自“ 1970-01-01 00:00:00 UTC”以来的1283351460秒,那么您确切地知道我在说什么时间点。(请参见下文Nir的出色回答)。[缺点:有效范围]。
在MySQL 5及更高版本中,TIMESTAMP值从当前时区转换为UTC以进行存储,并从UTC转换回当前时区以进行检索。(这仅发生在TIMESTAMP数据类型上,而不发生在其他类型上,例如DATETIME。)
默认情况下,每个连接的当前时区是服务器的时间。可以在每个连接的基础上设置时区,如MySQL服务器时区支持中所述。
我总是将DATETIME字段用于行元数据(创建或修改的日期)以外的任何内容。
至于提到的 MySQL文档中:
当您需要包含日期和时间信息的值时,将使用DATETIME类型。MySQL检索并以'YYYY-MM-DD HH:MM:SS'格式显示DATETIME值。支持的范围是“ 1000-01-01 00:00:00”到“ 9999-12-31 23:59:59”。
...
TIMESTAMP数据类型的UTC范围为'1970-01-01 00:00:01'至UTC'2038-01-09 03:14:07'。它具有不同的属性,具体取决于运行服务器的MySQL版本和SQL模式。
您很可能会达到一般使用的TIMESTAMP的下限-例如,存储生日。
new Date().getTime()
已经为您提供了64位值。
下面的示例显示TIMESTAMP
在更改time-zone to 'america/new_york'
where DATETIME
不变后日期类型如何更改值。
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 |
+---------------------+---------------------+
我已经将答案转换为文章,以便更多人可以找到有用的MySQL:日期时间与时间戳数据类型。
DATETIME
有效时间随时区的变化而变化,TIMESTAMP
并没有变化,但是人类的代表却发生了变化。
set time_zone="america/new_york"
;
主要区别在于DATETIME是常数,而TIMESTAMP受time_zone
设置影响。
因此,只有在跨时区拥有或将来有同步集群时,才有意义。
用简单的话来说:如果我在澳大利亚有一个数据库,并转储该数据库以在美国同步/填充一个数据库,则TIMESTAMP将更新以反映新时区的事件实时,而DATETIME会仍然反映事件在au时区的时间。
在应该使用TIMESTAMP的地方使用了DATETIME的一个很好的例子是在Facebook中,那里的服务器从不十分确定跨时区发生了什么时间。在一次对话中,时间说的是我在实际发送消息之前回复消息。(当然,如果发布时间而不是同步时间,则这也可能是由于消息传递软件中的时区转换错误造成的。)
我基于语义做出此决定。
当需要记录(或多或少)固定时间点时,请使用时间戳记。例如,将记录插入数据库中或发生某些用户操作时。
当日期/时间可以任意设置和更改时,我使用datetime字段。例如,当用户可以保存以后的更改约会时。
我建议使用既不 datetime或时间戳字段。如果您想代表一个特定的一天(例如生日),请使用DATE类型,但如果要更具体一些,则可能希望记录一个实际时刻而不是一个单位时间(天,周,月,年)。而不是使用DATETIME或TIMESTAMP,而使用BIGINT,并且只需存储自纪元以来的毫秒数(如果使用Java,则为System.currentTimeMillis())。这有几个优点:
此问题与如何在数据库中存储货币值(即$ 1.99)密切相关。您应该使用小数,还是数据库的Money类型,还是最差的Double?由于上面列出的许多相同原因,所有这三个选项都很糟糕。解决方案是使用BIGINT将货币价值存储为美分,然后在向用户显示价值时将美分转换为美元。数据库的工作是存储数据,而不是解释该数据。您在数据库(尤其是Oracle)中看到的所有这些奇特的数据类型几乎没有增加,并开始您进入供应商锁定的道路。
TIMESTAMP是4个字节,而DATETIME是8个字节。
http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html
但是就像scronide所说的那样,它的下限确实是1970年。尽管这对于将来可能发生的任何事情都非常有用;)
TIMESTAMP是四个字节,而DATETIME是八个字节。
时间戳在数据库上也更轻巧,索引速度更快。
当您需要包含日期和时间信息的值时,将使用DATETIME类型。MySQL检索并以'YYYY-MM-DD HH:MM:SS'格式显示DATETIME值。支持的范围是'1000-01-01 00:00:00'至'9999-12-31 23:59:59'。
TIMESTAMP数据类型的UTC范围为'1970-01-01 00:00:01'UTC至'2038-01-09 03:14:07'UTC。它具有不同的属性,具体取决于运行服务器的MySQL版本和SQL模式。
确实取决于应用程序。
考虑为用户在纽约的服务器上设置时间戳,以在上海约会。现在,当用户在上海聊天时,他可以从东京的镜像服务器访问相同的约会时间戳。他将在东京时间看到约会,而不是原来的纽约时间。
因此,对于表示用户时间的值(如约会或时间表),日期时间更好。无论服务器设置如何,它都允许用户控制所需的确切日期和时间。设置时间是设置时间,不受服务器的时区,用户的时区或夏时制的计算方式(是的,并且会更改)的影响。
另一方面,对于表示系统时间的值(例如付款交易,表修改或日志记录),请始终使用时间戳记。将服务器移至另一个时区,或在不同时区的服务器之间进行比较时,系统均不会受到影响。
时间戳在数据库上也更轻巧,索引速度更快。
任何最新的前端框架(Angular 1/2,react,Vue等)都可以轻松,自动地将您的UTC日期时间转换为本地时间。
另外:
(除非您可能会更改服务器的时区)
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' }}
此处提供所有本地化的时间格式:https: //docs.angularjs.org/api/ng/filter/date
SET time_zone = '+0:00';
用于UTC。
一个timestamp
字段是一个特例datetime
场。您可以创建timestamp
具有特殊属性的列。可以将其设置为在创建和/或更新时自行更新。
用“更大”的数据库术语来说,上面timestamp
有几个特殊情况的触发器。
正确的选择完全取决于您想做什么。
DATETIME,TIMESTAMP和DATE之间的比较
那是什么[.fraction]?
资料来源:
在使用MySQL和PHP时,我总是会使用Unix时间戳。这样做的主要原因是PHP中默认的date方法使用时间戳作为参数,因此不需要解析。
要在PHP中获得当前的Unix时间戳,只需time();
在MySQL中执行即可SELECT UNIX_TIMESTAMP();
。
根据我的经验,如果您希望只在其中插入一次的日期字段,并且不想对该特定字段进行任何更新或任何其他操作,请选择date time。
例如,考虑一个user
带有REGISTRATION DATE字段的表。在该user
表中,如果您想知道特定用户的上次登录时间,请使用时间戳类型的字段,以便该字段得到更新。
如果从phpMyAdmin创建表,则默认设置将在发生行更新时更新timestamp字段。如果您的时间戳字段未通过行更新进行更新,则可以使用以下查询使时间戳字段自动更新。
ALTER TABLE your_table
MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
时间戳记数据类型存储日期和时间,但以UTC格式存储,而不是像datetime那样以当前时区格式存储。当您获取数据时,时间戳再次将其转换为当前时区时间。
因此,假设您在美国,并且从具有美国时区的服务器获取数据。然后您将根据美国时区获得日期和时间。当时间戳记数据类型列的行被更新时,它总是自动更新。因此,跟踪上次更新特定行的时间可能很有用。
有关更多详细信息,您可以阅读博客文章Timestamp Vs Datetime。
SET time_zone = '+0:00';
(此处为UTC)在会话级别定义时区,以确保您从TIMESTAMP
值中获取/设置了什么,并避免依赖于可能更改的服务器time_zone默认值。
就我而言,我会尽可能将UTC设置为所有区域的时区:系统,数据库服务器等。如果我的客户需要另一个时区,那么我可以在应用程序上对其进行配置。
我几乎总是喜欢时间戳而不是日期时间字段,因为时间戳隐式包含时区。因此,由于从不同时区的用户访问应用程序的那一刻起,您就希望他们看到其本地时区中的日期和时间,因此与将数据保存在datetime字段中相比,此字段类型使操作起来非常容易。
另外,在将数据库迁移到具有其他时区的系统的情况下,使用时间戳会使我更有信心。更不用说当计算两个时刻之间的差并且两者之间的加法器时间改变并且需要1小时或更短的精度时可能出现的问题。
因此,总而言之,我重视时间戳的优点:
由于所有这些原因,我在可能的地方选择UTC和时间戳字段。而且我避免头痛;)
warranties.expires_at
今天的MySQL时间戳已不可能。
在表上执行UPDATE语句时,请注意时间戳的更改。如果您的表具有“名称”(varchar),“年龄”(int)和“ Date_Added”(时间戳)列,则运行以下DML语句
UPDATE table
SET age = 30
那么“ Date_Added”列中的每个单个值都将更改为当前时间戳。
ON UPDATE CURRENT_TIMESTAMP
主要区别:
TIMESTAMP用于跟踪记录的更改,并在每次记录更改时进行更新。DATETIME用于存储不受记录更改影响的特定和静态值。
TIMESTAMP还受与TIME ZONE相关的其他设置的影响。DATETIME是常数。
TIMESTAMP在内部将当前时区转换为UTC进行存储,并在检索过程中将其转换回当前时区。DATETIME无法做到这一点。
支持的TIMESTAMP范围:'1970-01-01 00:00:01'UTC到'2038-01-19 03:14:07'UTC DATETIME支持的范围:'1000-01-01 00:00:00'到'9999 -12-31 23:59:59′
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| 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. |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
datetime
在遇到许多与时区有关的问题和错误后,我停止在自己的应用程序中使用。恕我直言,使用timestamp
比datetime
大多数情况下更好。
当您问几点了?答案来了像'2019-02-05 21:18:30'之类的东西,它没有完成,没有定义答案,因为它缺少另一个部分,在哪个时区?华盛顿?莫斯科?北京?
使用不带时区的datetimes意味着您的应用程序仅处理1个时区,但是时间戳为您提供了好处,datetime
并且可以灵活地显示不同时区中的相同精确时间点。
在某些情况下,您会后悔使用datetime
并希望将数据存储在时间戳中。
为了让您的客户感到舒适,您想根据他们的首选时区向他们显示时间,而无需让他们进行数学运算并将时间转换为有意义的时区。您所需要做的就是更改时区,所有应用程序代码都将相同。(实际上,您应该始终在应用程序启动时定义时区,或者在PHP应用程序的情况下请求处理)
SET time_zone = '+2:00';
您更改了所居住的国家/地区,并继续维护数据,同时在其他时区查看数据(不更改实际数据)。
datetime
=应用程序支持1个时区(用于插入和选择)
timestamp
=应用程序支持任何时区(用于插入和选择)
该答案仅是为了强调时区的灵活性和时间戳的易用性,而没有涵盖列大小,范围或分数之类的任何其他差异。
date
,而其他字段使用timestamp
该字段怎么办。我认为这将引起一个新问题,因为被筛选的数据where
与时区更改不一致。
date
在发送查询之前解决列上的时区问题。
A TIMESTAMP
需要4个字节,而A DATETIME
需要8个字节。
我喜欢Unix时间戳,因为您可以转换为数字,而不必担心数字。另外,您可以添加/减去并获取持续时间等。然后将结果以任何格式转换为Date。此代码找出从文档时间戳到当前时间之间经过了多少分钟的时间。
$date = $item['pubdate']; (etc ...)
$unix_now = time();
$result = strtotime($date, $unix_now);
$unix_diff_min = (($unix_now - $result) / 60);
$min = round($unix_diff_min);