我阅读了this和根据时间戳的MySQL文档:
它可以保存从' 1970-01-01 00:00:01' (UTC)到 ' 2038-01-19 05:14:07' (世界标准时间) 。此范围是由MariaDB存储引起的 TIMESTAMP值为自1970-01-01以来的秒数 00:00:00' (UTC)。
因此所有与时间戳相关的操作都在UNIX_TIMESTAMP中完成,因为时间戳中没有存储时区信息。这是我的理解。
我当前时区:IST(+05:30) 在午夜之后,当日期在IST中更改但未在UTC中时,我执行了插入操作。我想如果我为IST做一个DATE(now())它应该显示昨天的存储记录,因为我认为UNIX_TIMESTAMP将用于时间戳比较,它将保持不变。
在下面的代码块中,您可以看到时区偏移为+05:30,这是IST。在2017年2月13日00:04 pm插入了ID = 5的记录。但是UTC_STAMP将在2017年2月12日某个18小时34分钟(5小时30分钟后)。所以日期不会改变UTC。我为2017年2月13日的日期做了一个选择声明,我想我会得到(1,2,3,5)记录,因为IST的2017年2月13日00:00的UTC表示仍然属于12thFeb的UTC日期,2017年。但我只得到ID = 5的记录。
Q.1 简而言之,我认为 value = 2017-02-13 将转换为UNIX_TIMESTAMP(数值),然后进行比较。我错过了什么?或者提一下db生成以下结果所采取的步骤?我希望我能解释自己。
Q.2 java.sql.Timestamp如何执行?它的工作方式类似于代码块中提到的,或者它首先将时间戳值转换为unix_timestamp然后进行转换,还是数据库内部实现比较时间戳的长值?
MariaDB [test]>SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM | +05:30 |
+--------------------+---------------------+
MariaDB [test]> desc t;
+-------+-----------+------+-----+-------------------+---------------- -------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-----------------------------+
| id | int(11) | YES | | NULL | |
| ts | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+--------------- --------------+
MariaDB [test]> select * from t;
+------+---------------------+
| id | ts |
+------+---------------------+
| 1 | 2017-02-12 22:10:35 |
| 2 | 2017-02-12 22:10:35 |
| 3 | 2017-02-12 22:13:06 |
| 4 | 2001-07-22 12:12:12 |
| 5 | 2017-02-13 00:04:01 |
+------+---------------------+
MariaDB [test]> select * from t where date(ts) = '2017-02-13';
+------+---------------------+
| id | ts |
+------+---------------------+
| 5 | 2017-02-13 00:04:01 |
+------+---------------------+
MariaDB [test]> set time_zone = '+00:00';
MariaDB [test]> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM | +00:00 |
+--------------------+---------------------+
MariaDB [test]> select * from t;
+------+---------------------+
| id | ts |
+------+---------------------+
| 1 | 2017-02-12 16:40:35 |
| 2 | 2017-02-12 16:40:35 |
| 3 | 2017-02-12 16:43:06 |
| 4 | 2001-07-22 06:42:12 |
| 5 | 2017-02-12 18:34:01 |
+------+---------------------+
MariaDB [test]> select * from t where date(ts) = '2017-02-12';
+------+---------------------+
| id | ts |
+------+---------------------+
| 1 | 2017-02-12 16:40:35 |
| 2 | 2017-02-12 16:40:35 |
| 3 | 2017-02-12 16:43:06 |
| 5 | 2017-02-12 18:34:01 |
+------+---------------------+
EDIT1:我尝试使用带有UTC时区的数据库服务器和IST作为应用服务器。在午夜之后,当IST改变其日期并且UTC没有 - 我重复插入并创建如上所述的操作。下面是记录和信息:
MariaDB [test]> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| UTC | UTC |
+--------------------+---------------------+
1 row in set (0.30 sec)
MariaDB [test]> select * from t ;
+----+---------------------+
| id | ts |
+----+---------------------+
| 1 | 2017-02-13 19:22:15 |
| 2 | 2017-02-13 19:22:15 |
| 3 | 2017-02-13 19:21:40 |
| 4 | 2001-07-22 12:12:12 |
| 5 | 2017-02-14 00:56:13 |
+----+---------------------+
5 rows in set (0.40 sec)
MariaDB [test]> select UTC_TIMESTAMP;
+---------------------+
| UTC_TIMESTAMP |
+---------------------+
| 2017-02-13 19:21:22 |
+---------------------+
1 row in set (0.38 sec)
并使用JDBC获得响应:
SELECT * FROM t WHERE date(ts) = date(:currentDate);
where, currentDate = Timestamp.from(Instant.now()); from Java
回应是:
[
{
"id": 1,
"timestamp1": 1486993935000
},
{
"id": 2,
"timestamp1": 1486993935000
},
{
"id": 3,
"timestamp1": 1486993900000
}
]
为什么记录(id = 5)没有来?并不意味着它寻找视觉表示而不是从UTC_TIMESTAMP数值中提取日期,如果它已经完成它将获取id = 5的记录。