Solr日期类型处理apache
solr控制台查询出的日期格式与实际时间少8个小时,由于咱们是东八区,推测是时区的缘由。json
形成这个问题的根源是东八区的人不习惯零时区的时间。其实,solr索引存储的时间并无少8小时,只是在时间格式化的时候,用的是UTC时间,由于咱们是东八区,UTC是零时区时间,因此日期展现的时候,看起来是慢了8小时。服务器
误区一:修改写入时间ide
为了解决这个问题,在solrJ写入时间时,修改时间,增长8小时。这种方案至关于篡改了数据,是不可取的。源码分析
误区二:修改服务器时区性能
为了解决这个问题,修改服务器的时区(或solr的时区)。集群服务器时间配置应该保持一致,不该该为了解决局部问题而破坏总体,因此不建议修改服务器时区。this
Solr日期类型在索引文件中存储的是long类型orm
经过Date的getTime获取long值,经过new Date(longValue)转换为时间。索引
Solr文本格式传输:日期为UTC标准格式(如:1972-05-20T17:33:18.772Z)ci
json、XML格式都属于文本格式。
SolrJ和Solr服务器都是根据本地时区来转换UTC,同时也是根据本地时区来将UTC字符串转换为Date类型。
Solr的Web控制台就是采用的文本传输格式,因此看见的时间是UTC格式字符串(滞后8小时)。
Solr二进制传输:日期为long类型
采用二进制传输时,与时区无关。
long值是经过date.getTime直接获取,
long值转换Date时,直接new Date(longValue);
文本传输
优势:保证UTC时间一致性,即使时区不一致的服务器依然能保证UTC时间的一致性
缺点:是数据报文比较大,性能很差。
适合场景:人机交互。
二进制传输
优势:数据紧凑,性能好。
缺点:不考虑时区,没法保证UTC时间一致。
场景:服务器间交互。通常企业集群的服务器时钟是统一配置的。
org.apache.solr.util.DateFormatUtil源码: 文本格式日期处理相关 public static final TimeZone CANONICAL_TZ = UTC; public static final Locale CANONICAL_LOCALE = Locale.ROOT; public static final String NOW = "NOW"; ... static class ISO8601CanonicalDateFormat extends SimpleDateFormat { protected NumberFormat millisParser = NumberFormat.getIntegerInstance(CANONICAL_LOCALE); protected NumberFormat millisFormat = new DecimalFormat (".###", new DecimalFormatSymbols(CANONICAL_LOCALE)); public ISO8601CanonicalDateFormat() { super("yyyy-MM-dd'T'HH:mm:ss", CANONICAL_LOCALE); this.setTimeZone(CANONICAL_TZ); } .... } ... org.apache.solr.common.util.JavaBinCodec源码: 二进制格式日期处理相关 if (val instanceof Date) { daos.writeByte(DATE); daos.writeLong(((Date) val).getTime()); return true; }