时间(数据库&JAVA&ES)

前言:时间在不同语言和工具中对应不同,了解相关工具和语言的时间,可以提高开发效率

目录:
一、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

image.png

【注】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
  1. 日期时间范围查询(查到日期时间记录)
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:02epoch_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

你可能感兴趣的:(时间(数据库&JAVA&ES))