问题
由于ES不能指定时区(也许将来会支持也说不一定),目前是时区始终是UTC。
- 如果存储是日期时间类型,则需考虑时区问题;
- 如果是字符串,除非直接比对,否则在转换为日期是会有时区问题;
- 如果是时间戳,即Long类型,同样需要考虑时区问题。
试验
执行的查询SQL命令:
POST http://localhost:9200/_sql?format=text
当前时间-默认
查询语句:
{"query": "SELECT CURRENT_TIMESTAMP as ts"}
返回结果:
ts
————————————-
2023-11-30T23:31:14.632Z
返回的结果,实际上与我上海时区的实际相差了8个小时,即默认返回的是UTC时间。
当前时间-上海时区
查询语句:
{"query": "SELECT CURRENT_TIMESTAMP as ts","time_zone":"Asia/Shanghai"}
返回结果:
ts
——————————————–
2023-12-01T07:33:26.840+08:00
从返回的结果可以看出,现在已经带时区信息,为东8区,并且与我系统时间一致。
时间戳-强转
查询语句:
{"query": "SELECT 1701387000000::timestamp as ts, 1701387000000::date as dt","time_zone":"Asia/Shanghai"}
返回结果:
ts |dt
———————————- -+————————————
2023-11-30T23:30:00.000Z|2023-11-30T00:00:00.000Z
从返回的结果可以看出,即便指定了时区参数,强转的日期,仍旧只会返回UTC时区值,而不受时区影响。
通过采用CAST也是一样,不受时区参数影响:
{"query": "SELECT CAST('2023-11-30T23:30:00.000Z' AS TIMESTAMP) as ct","time_zone":"Asia/Shanghai"}
返回结果:
ct
————————————
2023-11-30T23:30:00.000Z
时间戳-函数转换
查询语句:
{"query": "SELECT DATETIME_FORMAT(1701387000000::TIMESTAMP,'yyyy-MM-dd HH:mm:ss.SSS') as df","time_zone":"Asia/Shanghai"}
返回结果:
df
———————————-
2023-12-01 07:30:00.000
从返回的结果可以看出,即便指定了时区参数,强转的日期,人家只会返回UTC时区值。
日期解析-默认
查询语句:
{"query": "SELECT DATETIME_PARSE('2023-11-30 23:30:00.000','yyyy-MM-dd HH:mm:ss.SSS') as dp","time_zone":"Asia/Shanghai"}
返回结果:
dp
——————————————–
2023-11-30T23:30:00.000+08:00
从返回的结果可以看出,指定了时区参数,则该日期即按指定的时区解析。
日期解析-带时区
查询语句:
{"query": "SELECT DATETIME_PARSE('2023-11-30 23:30:00.000 UTC','yyyy-MM-dd HH:mm:ss.SSS VV') as dp","time_zone":"Asia/Shanghai"}
返回结果:
dp
——————————————-
2023-12-01T07:30:00.000+08:00
从返回的结果可以看出,指定了时区参数,由于字符串中指定了时间为UTC,而参数指定了上海时区,则结果返回了上海时区的结果。
结论
- 强转日期时间不受时区参数影响;
- 函数转换日期会依据指定时区返回。