Solrj将我的日期格式从UTC格式化为CEST

时间:2014-09-26 17:59:01

标签: java date datetime solr solrj

我刚刚在应用程序中发现了日期字段的问题。我有一个以SOLr格式索引的日期字段。例如,"parution_date": "2014-09-29T22:00:00Z",。当我使用数据透视表向Solr发出请求时,我希望获得此值,Solr将我的日期转换为CET(我在欧洲)。 这是我收到同一份文件的日期:Tue Sep 30 00:00:00 CEST 2014

正如您在此处所看到的,它不是将日期保持为原始格式(UTC),而是将日期转换为CEST。我想保留UTC格式,因为我使用此字段来研究一些文档。

对于此请求,我使用的是facet pivot。以下是我得到的结果:

for(PivotField pv : pivotFields){

        Date value = (Date) pv.getValue();
        String parutionDate = formatDate(value, DateHelper.DD_MM_YYYY_FORMAT);

    }

getValue方法返回一个对象,因此我必须将其强制转换为Date对象。

我看到了一些解决方案:

  • 当我向Solr发出请求时,将我的CEST日期转换为UTC,但我现在还不知道如何做。我是Solr的初学者。
  • 或将我的日期保留为UTC格式。

处理此问题的最佳解决方案是什么?任何帮助,将不胜感激。

4 个答案:

答案 0 :(得分:1)

看来Solr与您的问题无关。

java.util.Date有一个令人烦恼的坏功能,其中对象没有时区,但它的toString方法应用了JVM的当前默认时区。

最好的方法是避免使用java.util.Date和.Calendar类,因为它们非常麻烦。而是使用Joda-Time库或与Java 8捆绑在一起的新java.time包(受Joda-Time启发)。

Joda-Time 2.4中的示例。

java.util.Date date = ( java.util.Date ) PC.getValue();
DateTime dateTimeUtc = new DateTime( date, DateTimeZone.UTC );
String output = dateTimeUtc.toString();

调整到本地区域。

DateTime dateTimeBerlin = dateTimeUtc.withZone( DateTimeZone.forID( "Europe/Berlin" ) );

答案 1 :(得分:1)

我使用SolrJ时遇到了同样的问题,因为我只是使用toString()将所有属性值转换为字符串。 SolrJ要求Solr以javabin格式返回结果(通过使用HttpClient的调试级别记录URL中的wt-parameter),所以我假设java.util.Date对象在Solr端序列化并在SolrJ客户端反序列化并且此Date实例不包含任何时区信息。这就是为什么在调用toString()时将本地时区作为默认值。

因此,没有其他方法可以使用您选择的模式明确地格式化Date。

Apache Commons Lang软件包的DateFormatUtils类可以用作自编写工具的替代方法,如上面的DateHelper。

DateFormatUtils.format(yourDateObj, "yyyy-MM-dd'T'HH:mm:ss'Z'"); DateFormatUtils.format(yourDateObj, "yyyy-MM-dd'T'HH:mm:ss'Z'", TimeZone.getTimeZone("UTC"));

答案 2 :(得分:0)

Solr在UTC中工作。如果可能的话,您应该尝试将其保持在UTC中,并且只能转换为演示目的。

此外,问题是否可能发生在客户端库中,而不是Solr本身?尝试做一个Web查询,这个请求对应,看看你得到了什么。我很确定它都是UTC。

答案 3 :(得分:0)

我找到了解决问题的临时解决方案。我不得不在try / finally子句中手动更改时区。

Timezone default = null;

try {
   for(PivotField pv : pivotFields){

       default = Timezone.getDefault(); //save the default timezone
       Date value = (Date) pv.getValue();
       TimeZone.setDefault(TimeZone.getTimeZone("UTC")); // change it to UTC
       String parutionDate = formatDate(value, DateHelper.DD_MM_YYYY_FORMAT);
    }
 } finally {
    if(default != null){
       TimeZone.setDefault(default);
    }      
 }

现在非常难看的解决方案。我仍然对更好的解决方案感兴趣。

[编辑]我找到了更好的解决方案。我正在使用apache FastDateFormat中的commons-lang3,此类还可以接收时区作为参数。这是我的代码的修改版本:

    public class Mapper {

       public void mapMyObject(List<PivotField> pivotFields){

           for(PivotField pv : pivotFields){

            Date value = (Date) pv.getValue();
            String parutionDate = formatDate(value, DateHelper.DD_MM_YYYY_FORMAT);
        }
       }


        private String formatDate(Date date, String pattern){
           return DateHelper.getStringFromDateSolr(date, pattern);     
        } 
  }

方法getStringFromDateSolr定义如下:

public class DateHelper {

    public static String getStringFromDateSolr(Date date, String format) {
       return formatDate(date, FastDateFormat.getInstance(format, TimeZone.getTimeZone("UTC")));
   }

   private static String formatDate(Date date, FastDateFormat format) {
    if (date != null) {
        try {
            return format.format(date);
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
        }
    }
    return null;
}
}