Solr日期类型处理
Solr 如何处理日期类型
日期格式与实际时间晚8小时
solr控制台查询出的日期格式与实际时间少8个小时,因为我们是东八区,推测是时区的原因。
造成这个问题的根源是东八区的人不习惯零时区的时间。其实,solr索引存储的时间并没有少8小时,只是在时间格式化的时候,用的是UTC时间,因为我们是东八区,UTC是零时区时间,所以日期展示的时候,看起来是慢了8小时。
误区一:修改写入时间
为了解决这个问题,在solrJ写入时间时,修改时间,增加8小时。这种方案相当于篡改了数据,是不可取的。
误区二:修改服务器时区
为了解决这个问题,修改服务器的时区(或solr的时区)。集群服务器时间配置应该保持一致,不应该为了解决局部问题而破坏整体,所以不建议修改服务器时区。
Solr日期格式的传输与存储
Solr日期类型在索引文件中存储的是long类型
通过Date的getTime获取long值,通过new Date(longValue)转换为时间。
Solr文本格式传输:日期为UTC标准格式(如:1972-05-20T17:33:18.772Z)
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; }
转载于:https://blog.51cto.com/laoyuan2014/1721713