SEARCH-1286 date type casting errors (#27)

* [ SEARCH-1286 ] additional ThreadLocal + date format (UTC - msecs)

* [ SEARCH-1286 ] ThreadLocal + other minor refactoring + unit tests

* [ SEARCH-1286 ] Fixed Timezone issue in Unit tests

* [ SEARCH-1286 ] Fixed Timezone issue II in Unit tests

* [ SEARCH-1286 ] Fixed Locale issue in CachingDataFormat

* Merge branches 'fix/SEARCH-1286_date_type_casting_errors' and 'master' of https://github.com/Alfresco/alfresco-core into fix/SEARCH-1286_date_type_casting_errors

# Conflicts:
#	src/main/java/org/alfresco/util/CachingDateFormat.java
#	src/test/java/org/alfresco/util/CachingDateFormatTest.java
This commit is contained in:
Andrea Gazzarini
2018-11-30 12:06:37 +01:00
committed by GitHub
parent 7ab552310a
commit 51077e8ad0
2 changed files with 48 additions and 27 deletions

View File

@@ -18,7 +18,8 @@
*/
package org.alfresco.util;
import java.text.NumberFormat;
import static java.util.Arrays.stream;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
@@ -27,8 +28,6 @@ import java.util.*;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import static java.util.Arrays.stream;
/**
* Provides <b>thread safe</b> means of obtaining a cached date formatter.
* <p>
@@ -85,37 +84,34 @@ public class CachingDateFormat extends SimpleDateFormat
new StringAndResolution("yyyy", Calendar.YEAR)
};
private static ThreadLocal<SimpleDateFormat> S_LOCAL_DATE_FORMAT = ThreadLocal.withInitial(() -> newDateFormat(FORMAT_FULL_GENERIC));
static ThreadLocal<SimpleDateFormat> S_LOCAL_DATE_FORMAT = ThreadLocal.withInitial(() -> newDateFormat(FORMAT_FULL_GENERIC));
private static ThreadLocal<SimpleDateFormat> S_LOCAL_DATEONLY_FORMAT = ThreadLocal.withInitial(() -> newDateFormat(FORMAT_DATE_GENERIC));
static ThreadLocal<SimpleDateFormat> S_LOCAL_DATEONLY_FORMAT = ThreadLocal.withInitial(() -> newDateFormat(FORMAT_DATE_GENERIC));
private static ThreadLocal<SimpleDateFormat> S_LOCAL_TIMEONLY_FORMAT = ThreadLocal.withInitial(() -> newDateFormat(FORMAT_TIME_GENERIC));
static ThreadLocal<SimpleDateFormat> S_LOCAL_TIMEONLY_FORMAT = ThreadLocal.withInitial(() -> newDateFormat(FORMAT_TIME_GENERIC));
private static ThreadLocal<SimpleDateFormat> S_LOCAL_CMIS_SQL_DATETIME = ThreadLocal.withInitial(() -> newDateFormat(FORMAT_CMIS_SQL));
static ThreadLocal<SimpleDateFormat> S_LOCAL_CMIS_SQL_DATETIME = ThreadLocal.withInitial(() -> newDateFormat(FORMAT_CMIS_SQL));
private static ThreadLocal<SimpleDateFormat> S_LOCAL_SOLR_DATETIME = ThreadLocal.withInitial(()->
static ThreadLocal<SimpleDateFormat> S_LOCAL_SOLR_DATETIME = ThreadLocal.withInitial(()->
{
CachingDateFormat formatter = newDateFormat(FORMAT_SOLR);
CachingDateFormat formatter = newDateFormatWithLocale(FORMAT_SOLR, Locale.ENGLISH);
/*
SEARCH-1263
Apache Solr only supports the ISO 8601 date format:
UTC and western locale are mandatory (only Arabic numerals (0123456789) are supported)
*/
formatter.setTimeZone(TimeZone.getTimeZone(UTC));
formatter.setNumberFormat(NumberFormat.getNumberInstance(Locale.ENGLISH));
return formatter;
});
private static ThreadLocal<SimpleDateFormat> S_UTC_DATETIME_WITHOUT_MSECS = ThreadLocal.withInitial(() ->
static ThreadLocal<SimpleDateFormat> S_UTC_DATETIME_WITHOUT_MSECS = ThreadLocal.withInitial(() ->
{
CachingDateFormat formatter = newDateFormat(UTC_WITHOUT_MSECS);
CachingDateFormat formatter = newDateFormatWithLocale(UTC_WITHOUT_MSECS, Locale.ENGLISH);
formatter.setTimeZone(TimeZone.getTimeZone(UTC));
formatter.setNumberFormat(NumberFormat.getNumberInstance(Locale.ENGLISH));
return formatter;
});
private static ThreadLocal<SimpleDateFormatAndResolution[]> S_LENIENT_PARSERS =
static ThreadLocal<SimpleDateFormatAndResolution[]> S_LENIENT_PARSERS =
ThreadLocal.withInitial(() ->
stream(LENIENT_FORMATS)
.map(format -> {
@@ -126,6 +122,11 @@ public class CachingDateFormat extends SimpleDateFormat
private Map<String, Date> cacheDates = new WeakHashMap<>(89);
private CachingDateFormat(String pattern, Locale locale)
{
super(pattern, locale);
}
private CachingDateFormat(String pattern)
{
super(pattern);
@@ -325,8 +326,6 @@ public class CachingDateFormat extends SimpleDateFormat
}
throw new ParseException("Unknown date format", 0);
}
public static SimpleDateFormatAndResolution[] getLenientFormatters()
@@ -403,4 +402,18 @@ public class CachingDateFormat extends SimpleDateFormat
formatter.setLenient(false);
return formatter;
}
/**
* Creates a new non-lenient localised {@link CachingDateFormat} instance.
*
* @param pattern the date / datetime pattern.
* @param locale the locale.
* @return new non-lenient {@link CachingDateFormat} instance.
*/
private static CachingDateFormat newDateFormatWithLocale(String pattern, Locale locale)
{
CachingDateFormat formatter = new CachingDateFormat(pattern, locale);
formatter.setLenient(false);
return formatter;
}
}

View File

@@ -18,7 +18,12 @@
*/
package org.alfresco.util;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.text.SimpleDateFormat;
@@ -29,24 +34,26 @@ import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
public class CachingDateFormatTest
{
private final LocalDateTime REFERENCE_DATE_TIME = LocalDateTime.of(2018, 4, 1, 10, 0); //2018-04-01 at 10:00am
private final Locale defaultLocale = Locale.getDefault();
@Before
public void setUp()
{
CachingDateFormat.S_LOCAL_SOLR_DATETIME.remove();
}
@Test
public void solrDatetimeFormat_DateNotUTC_shouldReturnISO8601DateString()
public void solrDatetimeFormat_shouldFormatTheMinDate()
{
Date shanghaiDate = testDate("Asia/Shanghai");
SimpleDateFormat solrDatetimeFormat = CachingDateFormat.getSolrDatetimeFormat();
SimpleDateFormat solrDatetimeFormat = CachingDateFormat.getSolrDatetimeFormatWithoutMsecs();
String formattedDate = solrDatetimeFormat.format(shanghaiDate);
assertThat(formattedDate,is("2018-04-01T02:00:00.000Z"));
assertThat(formattedDate,is("2018-04-01T02:00:00Z"));
}
@Test
@@ -54,6 +61,7 @@ public class CachingDateFormatTest
{
for(Locale currentLocale:Locale.getAvailableLocales())
{
CachingDateFormat.S_LOCAL_SOLR_DATETIME.remove();
Locale.setDefault(currentLocale);
Date utcDate = testDate("UTC");