前言:时间在不同语言和工具中对应不同,了解相关工具和语言的时间,可以提高开发效率
目录:
一、Java和mysql时间对应
二、时间戳概念
三、java时间
四、mysql时间
—— 4.1 时间datetime转换为long格式
—— 4.2 时间long转换为datetime格式
五、ES时间
六、实战
七、参考
一、Java和mysql时间对应
java | mysql | 数据库显示 |
---|---|---|
new Date(java.util) | datetime | yyyy-MM-dd HH:mm:ss |
long (eg:1605199171970/1605202879) | datetime | 0000-00-00 00:00:00(全都是0) |
二、时间戳概念
时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。
时间戳分为秒级(10位数字)和毫秒级的时间戳(13位数字)
三、java时间
new Date()
new Date()的为毫秒级的时间
the milliseconds since January 1, 1970, 00:00:00 GMT.
System.out.println(new Date(1605202879000L));
四、mysql时间
4.1 时间datetime转换为long格式
SELECT UNIX_TIMESTAMP(NOW()); // 不区分大小写
+-----------------------+
| unix_timestamp(now()) |
+-----------------------+
| 1605202879 |
+-----------------------+
4.2 时间long转换为datetime格式
- 秒级时间戳
SELECT FROM_UNIXTIME(1605202879); // 2020-11-13 01:41:19
+---------------------------+
| FROM_UNIXTIME(1605202879) |
+---------------------------+
| 2020-11-13 01:41:19 |
+---------------------------+
- 毫秒级时间戳
SELECT FROM_UNIXTIME(1605199171970); // NULL
+------------------------------+
| FROM_UNIXTIME(1605199171970) |
+------------------------------+
| NULL |
+------------------------------+
【注】mysql命令下select version();查看版本,测试版本为5.6.23
4.3 MySQL DATE、DATETIME、TIMESTAMP
【注】TIMESTAMP表达范围快过期了
五、ES时间
ES可以使用"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"来指定多个格式的日期,会自动进行匹配
PUT my-index-datetest
{
"mappings": {
"properties": {
"date": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
5.1 es日期测试
- 日期准备
时间戳(秒级) | 时间戳(毫秒级) | 时间日期 |
---|---|---|
1601481600 | 1601481600000 | 2020-10-01 00:00:00 |
1601481601 | 1601481601000 | 2020-10-01 00:00:01 |
1601481602 | 1601481602000 | 2020-10-01 00:00:02 |
- 新增索引
curl -X PUT 127.0.0.1:9200/my-datetest-index -H 'Content-Type: application/json' -d '{ "mappings": { "properties": { "testdate": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } } }' --user superuser:superman
- 查看插入索引
curl 127.0.0.1:9200/my-datetest-index --user superuser:superman
- 插入文档
// 秒级时间戳 1601481601
curl -X PUT 127.0.0.1:9200/my-datetest-index/_doc/1 -H 'Content-Type: application/json' -d '{ "testdate" : 1601481601 }' --user superuser:superman
// 毫秒级时间戳 1601481601001
curl -X PUT 127.0.0.1:9200/my-datetest-index/_doc/2 -H 'Content-Type: application/json' -d '{ "testdate" : 1601481601001 }' --user superuser:superman
// yyyy-MM-dd HH:mm:ss格式时间 2020-10-01 00:00:01
curl -X PUT 127.0.0.1:9200/my-datetest-index/_doc/3 -H 'Content-Type: application/json' -d '{ "testdate" : "2020-10-01 00:00:01" }' --user superuser:superman
- 查看所有文档
curl 127.0.0.1:9200/my-datetest-index/_doc/_search --user superuser:superman
插入的文档testdata字段按照匹配到的类型,如果不指定format,插入不能转换的时间会报错
{
"took":518,
"timed_out":false,
"_shards":{
"total":1,
"successful":1,
"skipped":0,
"failed":0
},
"hits":{
"total":{
"value":3,
"relation":"eq"
},
"max_score":1,
"hits":[
{
"_index":"my-datetest-index",
"_type":"_doc",
"_id":"1",
"_score":1,
"_source":{
"testdate":1601481601
}
},
{
"_index":"my-datetest-index",
"_type":"_doc",
"_id":"2",
"_score":1,
"_source":{
"testdate":1601481601001
}
},
{
"_index":"my-datetest-index",
"_type":"_doc",
"_id":"3",
"_score":1,
"_source":{
"testdate":"2020-10-01 00:00:01"
}
}
]
}
}
- 查询时间范围
{
"query":{
"range":{
"testdate":{
"lte":1601481602,
"gte":1601481600,
"format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
- 时间范围查询
{
"query":{
"range":{
"testdate":{
"lte":1601481602,
"gte":1601481600,
"format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
1)时间戳秒级范围查询 (查到时间戳记录)
curl 127.0.0.1:9200/my-datetest-index/_doc/_search -H 'Content-Type: application/json' -d '{ "query":{ "range":{ "testdate":{ "lte":1601481602, "gte":1601481600, "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } } }' --user superuser:superman
{
... ...
"hits":[
{
"_index":"my-datetest-index",
"_type":"_doc",
"_id":"1",
"_score":1,
"_source":{
"testdate":1601481601
}
}
]
... ...
}
2)时间戳毫秒秒级范围查询 (查到时间戳记录)
curl 127.0.0.1:9200/my-datetest-index/_doc/_search -H 'Content-Type: application/json' -d '{ "query":{ "range":{ "testdate":{ "lte":"1601481602000", "gte":"1601481600000", "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } } }' --user superuser:superman
{
... ...
"hits":[
{
"_index":"my-datetest-index",
"_type":"_doc",
"_id":"2",
"_score":1,
"_source":{
"testdate":1601481601001
}
}
]
... ...
}
把毫秒级时间戳转为yyyy-MM-dd HH:mm:ss比较
【注】报错,不能把时间戳转为yyyy-MM-dd HH:mm:ss格式
failed to parse date field [1601481600000] with format [yyyy-MM-dd HH:mm:ss]: [failed to parse date field [1601481600000] with format [yyyy-MM-dd HH:mm:ss]]
curl 127.0.0.1:9200/my-datetest-index/_doc/_search -H 'Content-Type: application/json' -d '{ "query":{ "range":{ "testdate":{ "lte":1601481602000, "gte":1601481600000, "format":"yyyy-MM-dd HH:mm:ss" } } } }' --user superuser:superman
- 日期时间范围查询(查到日期时间记录)
curl 127.0.0.1:9200/my-datetest-index/_doc/_search -H 'Content-Type: application/json' -d '{ "query":{ "range":{ "testdate":{ "lte":"2020-10-01 00:00:02", "gte":"2020-10-01 00:00:00", "format":"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } } }' --user superuser:superman
{
... ...
"hits":[
{
"_index":"my-datetest-index",
"_type":"_doc",
"_id":"3",
"_score":1,
"_source":{
"testdate":"2020-10-01 00:00:01"
}
}
]
... ...
}
将时间转为时间戳
2020-10-01 00:00:02
转epoch_millis
报错
failed to parse date field [2020-10-01 00:00:00] with format [epoch_millis]: [failed to parse date field [2020-10-01 00:00:00] with format [epoch_millis]]"}]
curl 127.0.0.1:9200/my-datetest-index/_doc/_search -H 'Content-Type: application/json' -d '{ "query":{ "range":{ "testdate":{ "lte":"2020-10-01 00:00:02", "gte":"2020-10-01 00:00:00", "format":"epoch_millis" } } } }' --user superuser:superman
【总结】
ES插入时指定format可以将匹配改format的时间格式插入,但是在比较过程中,只会比较相同格式的时间,而不是转换成统一格式进行比较
六、实战
在实际项目中,
java中使用的new Date()(java.util)
- 写数据库
mybatis默认转化为了时间戳(参数打印:2020-11-13 03:37:14.386(Timestamp)
),数据库的日期格式是datetime,所以会将TimeStamp转为datetime
数据库时间字段显示为2020-11-13 03:37:14
- 写es
java new Date写入es写的是毫秒级时间戳
1605238634386
七、参考
【1】elasticsearch reference: Date field type
【2】ES 22 - Elasticsearch中如何进行日期(数值)范围查询
【3】ElasticSearch中的date类型
【4】在Java中对mysql数据库插入datetime类型数据
【5】JAVA中如何将以Date型的数据保存到数据库以Datetime型的字段中
【6】mysql关联修改SQL及long与datetime类型相互转换
【7】MySQL为什么不支持毫秒/微秒精度? (5.6.5后已经支持)
【8】MySQL 时间类型 DATE、DATETIME和TIMESTAMP