Reverting the change introducing IsoLocal.ROOT and introducing IsoCalendarDataProvider that defaults start of the week to Monday and requires minimum 4 days in first week of a year. This extension is using java SPI mechanism and defaults for Locale.ROOT only. It require jvm property java.locale.providers to be set with SPI,COMPAT closes #41670 backport #48209
This commit is contained in:
parent
9c75f14a9f
commit
aaa6209be6
|
@ -842,6 +842,12 @@ class BuildPlugin implements Plugin<Project> {
|
||||||
if ((ext.get('runtimeJavaVersion') as JavaVersion) >= JavaVersion.VERSION_1_9) {
|
if ((ext.get('runtimeJavaVersion') as JavaVersion) >= JavaVersion.VERSION_1_9) {
|
||||||
test.jvmArgs '--illegal-access=warn'
|
test.jvmArgs '--illegal-access=warn'
|
||||||
}
|
}
|
||||||
|
//TODO remove once jvm.options are added to test system properties
|
||||||
|
if ((ext.get('runtimeJavaVersion') as JavaVersion) == JavaVersion.VERSION_1_8) {
|
||||||
|
test.systemProperty ('java.locale.providers','SPI,JRE')
|
||||||
|
} else if ((ext.get('runtimeJavaVersion') as JavaVersion) >= JavaVersion.VERSION_1_9) {
|
||||||
|
test.systemProperty ('java.locale.providers','SPI,COMPAT')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test.jvmArgumentProviders.add(nonInputProperties)
|
test.jvmArgumentProviders.add(nonInputProperties)
|
||||||
|
@ -876,6 +882,7 @@ class BuildPlugin implements Plugin<Project> {
|
||||||
'tests.security.manager': 'true',
|
'tests.security.manager': 'true',
|
||||||
'jna.nosys': 'true'
|
'jna.nosys': 'true'
|
||||||
|
|
||||||
|
|
||||||
// ignore changing test seed when build is passed -Dignore.tests.seed for cacheability experimentation
|
// ignore changing test seed when build is passed -Dignore.tests.seed for cacheability experimentation
|
||||||
if (System.getProperty('ignore.tests.seed') != null) {
|
if (System.getProperty('ignore.tests.seed') != null) {
|
||||||
nonInputProperties.systemProperty('tests.seed', project.property('testSeed'))
|
nonInputProperties.systemProperty('tests.seed', project.property('testSeed'))
|
||||||
|
|
|
@ -37,7 +37,6 @@ import java.time.format.SignStyle;
|
||||||
import java.time.temporal.ChronoField;
|
import java.time.temporal.ChronoField;
|
||||||
import java.time.temporal.IsoFields;
|
import java.time.temporal.IsoFields;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.time.temporal.TemporalAdjusters;
|
|
||||||
import java.time.temporal.TemporalQueries;
|
import java.time.temporal.TemporalQueries;
|
||||||
import java.time.temporal.TemporalQuery;
|
import java.time.temporal.TemporalQuery;
|
||||||
import java.time.temporal.WeekFields;
|
import java.time.temporal.WeekFields;
|
||||||
|
@ -53,6 +52,7 @@ import static java.time.temporal.ChronoField.NANO_OF_SECOND;
|
||||||
import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
|
import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
|
||||||
|
|
||||||
public class DateFormatters {
|
public class DateFormatters {
|
||||||
|
public static final WeekFields WEEK_FIELDS = WeekFields.of(DayOfWeek.MONDAY,4);
|
||||||
|
|
||||||
private static final DateTimeFormatter TIME_ZONE_FORMATTER_NO_COLON = new DateTimeFormatterBuilder()
|
private static final DateTimeFormatter TIME_ZONE_FORMATTER_NO_COLON = new DateTimeFormatterBuilder()
|
||||||
.appendOffset("+HHmm", "Z")
|
.appendOffset("+HHmm", "Z")
|
||||||
|
@ -946,14 +946,14 @@ public class DateFormatters {
|
||||||
* Returns a formatter for a four digit weekyear
|
* Returns a formatter for a four digit weekyear
|
||||||
*/
|
*/
|
||||||
private static final DateFormatter STRICT_WEEKYEAR = new JavaDateFormatter("strict_weekyear", new DateTimeFormatterBuilder()
|
private static final DateFormatter STRICT_WEEKYEAR = new JavaDateFormatter("strict_weekyear", new DateTimeFormatterBuilder()
|
||||||
.appendValue(WeekFields.ISO.weekBasedYear(), 4, 10, SignStyle.EXCEEDS_PAD)
|
.appendValue(WEEK_FIELDS.weekBasedYear(), 4, 10, SignStyle.EXCEEDS_PAD)
|
||||||
.toFormatter(Locale.ROOT)
|
.toFormatter(Locale.ROOT)
|
||||||
.withResolverStyle(ResolverStyle.STRICT));
|
.withResolverStyle(ResolverStyle.STRICT));
|
||||||
|
|
||||||
private static final DateTimeFormatter STRICT_WEEKYEAR_WEEK_FORMATTER = new DateTimeFormatterBuilder()
|
private static final DateTimeFormatter STRICT_WEEKYEAR_WEEK_FORMATTER = new DateTimeFormatterBuilder()
|
||||||
.appendValue(WeekFields.ISO.weekBasedYear(), 4, 10, SignStyle.EXCEEDS_PAD)
|
.appendValue(WEEK_FIELDS.weekBasedYear(), 4, 10, SignStyle.EXCEEDS_PAD)
|
||||||
.appendLiteral("-W")
|
.appendLiteral("-W")
|
||||||
.appendValue(WeekFields.ISO.weekOfWeekBasedYear(), 2, 2, SignStyle.NOT_NEGATIVE)
|
.appendValue(WEEK_FIELDS.weekOfWeekBasedYear(), 2, 2, SignStyle.NOT_NEGATIVE)
|
||||||
.toFormatter(Locale.ROOT)
|
.toFormatter(Locale.ROOT)
|
||||||
.withResolverStyle(ResolverStyle.STRICT);
|
.withResolverStyle(ResolverStyle.STRICT);
|
||||||
|
|
||||||
|
@ -972,7 +972,7 @@ public class DateFormatters {
|
||||||
new DateTimeFormatterBuilder()
|
new DateTimeFormatterBuilder()
|
||||||
.append(STRICT_WEEKYEAR_WEEK_FORMATTER)
|
.append(STRICT_WEEKYEAR_WEEK_FORMATTER)
|
||||||
.appendLiteral("-")
|
.appendLiteral("-")
|
||||||
.appendValue(WeekFields.ISO.dayOfWeek())
|
.appendValue(WEEK_FIELDS.dayOfWeek())
|
||||||
.toFormatter(Locale.ROOT)
|
.toFormatter(Locale.ROOT)
|
||||||
.withResolverStyle(ResolverStyle.STRICT));
|
.withResolverStyle(ResolverStyle.STRICT));
|
||||||
|
|
||||||
|
@ -1162,7 +1162,7 @@ public class DateFormatters {
|
||||||
* Returns a formatter for a four digit weekyear. (YYYY)
|
* Returns a formatter for a four digit weekyear. (YYYY)
|
||||||
*/
|
*/
|
||||||
private static final DateFormatter WEEK_YEAR = new JavaDateFormatter("week_year",
|
private static final DateFormatter WEEK_YEAR = new JavaDateFormatter("week_year",
|
||||||
new DateTimeFormatterBuilder().appendValue(WeekFields.ISO.weekBasedYear()).toFormatter(Locale.ROOT)
|
new DateTimeFormatterBuilder().appendValue(WEEK_FIELDS.weekBasedYear()).toFormatter(Locale.ROOT)
|
||||||
.withResolverStyle(ResolverStyle.STRICT));
|
.withResolverStyle(ResolverStyle.STRICT));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1591,9 +1591,9 @@ public class DateFormatters {
|
||||||
*/
|
*/
|
||||||
private static final DateFormatter WEEKYEAR_WEEK = new JavaDateFormatter("weekyear_week", STRICT_WEEKYEAR_WEEK_FORMATTER,
|
private static final DateFormatter WEEKYEAR_WEEK = new JavaDateFormatter("weekyear_week", STRICT_WEEKYEAR_WEEK_FORMATTER,
|
||||||
new DateTimeFormatterBuilder()
|
new DateTimeFormatterBuilder()
|
||||||
.appendValue(WeekFields.ISO.weekBasedYear())
|
.appendValue(WEEK_FIELDS.weekBasedYear())
|
||||||
.appendLiteral("-W")
|
.appendLiteral("-W")
|
||||||
.appendValue(WeekFields.ISO.weekOfWeekBasedYear())
|
.appendValue(WEEK_FIELDS.weekOfWeekBasedYear())
|
||||||
.toFormatter(Locale.ROOT)
|
.toFormatter(Locale.ROOT)
|
||||||
.withResolverStyle(ResolverStyle.STRICT)
|
.withResolverStyle(ResolverStyle.STRICT)
|
||||||
);
|
);
|
||||||
|
@ -1606,15 +1606,15 @@ public class DateFormatters {
|
||||||
new DateTimeFormatterBuilder()
|
new DateTimeFormatterBuilder()
|
||||||
.append(STRICT_WEEKYEAR_WEEK_FORMATTER)
|
.append(STRICT_WEEKYEAR_WEEK_FORMATTER)
|
||||||
.appendLiteral("-")
|
.appendLiteral("-")
|
||||||
.appendValue(WeekFields.ISO.dayOfWeek())
|
.appendValue(WEEK_FIELDS.dayOfWeek())
|
||||||
.toFormatter(Locale.ROOT)
|
.toFormatter(Locale.ROOT)
|
||||||
.withResolverStyle(ResolverStyle.STRICT),
|
.withResolverStyle(ResolverStyle.STRICT),
|
||||||
new DateTimeFormatterBuilder()
|
new DateTimeFormatterBuilder()
|
||||||
.appendValue(WeekFields.ISO.weekBasedYear())
|
.appendValue(WEEK_FIELDS.weekBasedYear())
|
||||||
.appendLiteral("-W")
|
.appendLiteral("-W")
|
||||||
.appendValue(WeekFields.ISO.weekOfWeekBasedYear())
|
.appendValue(WEEK_FIELDS.weekOfWeekBasedYear())
|
||||||
.appendLiteral("-")
|
.appendLiteral("-")
|
||||||
.appendValue(WeekFields.ISO.dayOfWeek())
|
.appendValue(WEEK_FIELDS.dayOfWeek())
|
||||||
.toFormatter(Locale.ROOT)
|
.toFormatter(Locale.ROOT)
|
||||||
.withResolverStyle(ResolverStyle.STRICT)
|
.withResolverStyle(ResolverStyle.STRICT)
|
||||||
);
|
);
|
||||||
|
@ -1858,7 +1858,7 @@ public class DateFormatters {
|
||||||
} else if (isLocalDateSet) {
|
} else if (isLocalDateSet) {
|
||||||
return localDate.atStartOfDay(zoneId);
|
return localDate.atStartOfDay(zoneId);
|
||||||
} else if (isLocalTimeSet) {
|
} else if (isLocalTimeSet) {
|
||||||
return of(getLocaldate(accessor), localTime, zoneId);
|
return of(getLocalDate(accessor), localTime, zoneId);
|
||||||
} else if (accessor.isSupported(ChronoField.YEAR) || accessor.isSupported(ChronoField.YEAR_OF_ERA) ) {
|
} else if (accessor.isSupported(ChronoField.YEAR) || accessor.isSupported(ChronoField.YEAR_OF_ERA) ) {
|
||||||
if (accessor.isSupported(MONTH_OF_YEAR)) {
|
if (accessor.isSupported(MONTH_OF_YEAR)) {
|
||||||
return getFirstOfMonth(accessor).atStartOfDay(zoneId);
|
return getFirstOfMonth(accessor).atStartOfDay(zoneId);
|
||||||
|
@ -1868,19 +1868,9 @@ public class DateFormatters {
|
||||||
}
|
}
|
||||||
} else if (accessor.isSupported(MONTH_OF_YEAR)) {
|
} else if (accessor.isSupported(MONTH_OF_YEAR)) {
|
||||||
// missing year, falling back to the epoch and then filling
|
// missing year, falling back to the epoch and then filling
|
||||||
return getLocaldate(accessor).atStartOfDay(zoneId);
|
return getLocalDate(accessor).atStartOfDay(zoneId);
|
||||||
} else if (accessor.isSupported(WeekFields.ISO.weekBasedYear())) {
|
} else if (accessor.isSupported(WEEK_FIELDS.weekBasedYear())) {
|
||||||
if (accessor.isSupported(WeekFields.ISO.weekOfWeekBasedYear())) {
|
return localDateFromWeekBasedDate(accessor).atStartOfDay(zoneId);
|
||||||
return Year.of(accessor.get(WeekFields.ISO.weekBasedYear()))
|
|
||||||
.atDay(1)
|
|
||||||
.with(WeekFields.ISO.weekOfWeekBasedYear(), accessor.getLong(WeekFields.ISO.weekOfWeekBasedYear()))
|
|
||||||
.atStartOfDay(zoneId);
|
|
||||||
} else {
|
|
||||||
return Year.of(accessor.get(WeekFields.ISO.weekBasedYear()))
|
|
||||||
.atDay(1)
|
|
||||||
.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY))
|
|
||||||
.atStartOfDay(zoneId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// we should not reach this piece of code, everything being parsed we should be able to
|
// we should not reach this piece of code, everything being parsed we should be able to
|
||||||
|
@ -1888,6 +1878,19 @@ public class DateFormatters {
|
||||||
throw new IllegalArgumentException("temporal accessor [" + accessor + "] cannot be converted to zoned date time");
|
throw new IllegalArgumentException("temporal accessor [" + accessor + "] cannot be converted to zoned date time");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static LocalDate localDateFromWeekBasedDate(TemporalAccessor accessor) {
|
||||||
|
if (accessor.isSupported(WEEK_FIELDS.weekOfWeekBasedYear())) {
|
||||||
|
return LocalDate.ofEpochDay(0)
|
||||||
|
.with(WEEK_FIELDS.weekBasedYear(), accessor.get(WEEK_FIELDS.weekBasedYear()))
|
||||||
|
.with(WEEK_FIELDS.weekOfWeekBasedYear(), accessor.get(WEEK_FIELDS.weekOfWeekBasedYear()))
|
||||||
|
.with(ChronoField.DAY_OF_WEEK, WEEK_FIELDS.getFirstDayOfWeek().getValue());
|
||||||
|
} else {
|
||||||
|
return LocalDate.ofEpochDay(0)
|
||||||
|
.with(WEEK_FIELDS.weekBasedYear(), accessor.get(WEEK_FIELDS.weekBasedYear()))
|
||||||
|
.with(ChronoField.DAY_OF_WEEK, WEEK_FIELDS.getFirstDayOfWeek().getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* extending the java.time.temporal.TemporalQueries.LOCAL_DATE implementation to also create local dates
|
* extending the java.time.temporal.TemporalQueries.LOCAL_DATE implementation to also create local dates
|
||||||
* when YearOfEra was used instead of Year.
|
* when YearOfEra was used instead of Year.
|
||||||
|
@ -1915,9 +1918,11 @@ public class DateFormatters {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static LocalDate getLocaldate(TemporalAccessor accessor) {
|
private static LocalDate getLocalDate(TemporalAccessor accessor) {
|
||||||
int year = getYear(accessor);
|
if (accessor.isSupported(WEEK_FIELDS.weekBasedYear())) {
|
||||||
if (accessor.isSupported(MONTH_OF_YEAR)) {
|
return localDateFromWeekBasedDate(accessor);
|
||||||
|
} else if (accessor.isSupported(MONTH_OF_YEAR)) {
|
||||||
|
int year = getYear(accessor);
|
||||||
if (accessor.isSupported(DAY_OF_MONTH)) {
|
if (accessor.isSupported(DAY_OF_MONTH)) {
|
||||||
return LocalDate.of(year, accessor.get(MONTH_OF_YEAR), accessor.get(DAY_OF_MONTH));
|
return LocalDate.of(year, accessor.get(MONTH_OF_YEAR), accessor.get(DAY_OF_MONTH));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Licensed to Elasticsearch under one or more contributor
|
||||||
|
* license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright
|
||||||
|
* ownership. Elasticsearch licenses this file to you under
|
||||||
|
* the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.common.time;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.spi.CalendarDataProvider;
|
||||||
|
|
||||||
|
public class IsoCalendarDataProvider extends CalendarDataProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getFirstDayOfWeek(Locale locale) {
|
||||||
|
return Calendar.MONDAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinimalDaysInFirstWeek(Locale locale) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Locale[] getAvailableLocales() {
|
||||||
|
return new Locale[]{Locale.ROOT};
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ import org.apache.logging.log4j.LogManager;
|
||||||
import org.elasticsearch.common.SuppressForbidden;
|
import org.elasticsearch.common.SuppressForbidden;
|
||||||
import org.elasticsearch.common.logging.DeprecationLogger;
|
import org.elasticsearch.common.logging.DeprecationLogger;
|
||||||
import org.elasticsearch.common.time.DateFormatter;
|
import org.elasticsearch.common.time.DateFormatter;
|
||||||
|
import org.elasticsearch.common.time.DateFormatters;
|
||||||
import org.elasticsearch.common.time.DateUtils;
|
import org.elasticsearch.common.time.DateUtils;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
|
||||||
|
@ -50,7 +51,6 @@ import java.time.temporal.TemporalField;
|
||||||
import java.time.temporal.TemporalQuery;
|
import java.time.temporal.TemporalQuery;
|
||||||
import java.time.temporal.TemporalUnit;
|
import java.time.temporal.TemporalUnit;
|
||||||
import java.time.temporal.ValueRange;
|
import java.time.temporal.ValueRange;
|
||||||
import java.time.temporal.WeekFields;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@ -474,14 +474,14 @@ public class JodaCompatibleZonedDateTime
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public int getWeekOfWeekyear() {
|
public int getWeekOfWeekyear() {
|
||||||
logDeprecatedMethod("getWeekOfWeekyear()", "get(WeekFields.ISO.weekOfWeekBasedYear())");
|
logDeprecatedMethod("getWeekOfWeekyear()", "get(DateFormatters.WEEK_FIELDS.weekOfWeekBasedYear())");
|
||||||
return dt.get(WeekFields.ISO.weekOfWeekBasedYear());
|
return dt.get(DateFormatters.WEEK_FIELDS.weekOfWeekBasedYear());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public int getWeekyear() {
|
public int getWeekyear() {
|
||||||
logDeprecatedMethod("getWeekyear()", "get(WeekFields.ISO.weekBasedYear())");
|
logDeprecatedMethod("getWeekyear()", "get(DateFormatters.WEEK_FIELDS.weekBasedYear())");
|
||||||
return dt.get(WeekFields.ISO.weekBasedYear());
|
return dt.get(DateFormatters.WEEK_FIELDS.weekBasedYear());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
org.elasticsearch.common.time.IsoCalendarDataProvider
|
|
@ -37,9 +37,9 @@ import java.time.format.DateTimeFormatter;
|
||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.core.IsEqual.equalTo;
|
|
||||||
|
|
||||||
public class JavaJodaTimeDuellingTests extends ESTestCase {
|
public class JavaJodaTimeDuellingTests extends ESTestCase {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.elasticsearch.common.time;
|
package org.elasticsearch.common.time;
|
||||||
|
|
||||||
|
import org.elasticsearch.bootstrap.JavaVersion;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
|
@ -40,6 +41,35 @@ import static org.hamcrest.Matchers.sameInstance;
|
||||||
|
|
||||||
public class DateFormattersTests extends ESTestCase {
|
public class DateFormattersTests extends ESTestCase {
|
||||||
|
|
||||||
|
public void testWeekBasedDates() {
|
||||||
|
assumeFalse("won't work in jdk8 " +
|
||||||
|
"because SPI mechanism is not looking at classpath - needs ISOCalendarDataProvider in jre's ext/libs",
|
||||||
|
JavaVersion.current().equals(JavaVersion.parse("8")));
|
||||||
|
|
||||||
|
// as per WeekFields.ISO first week starts on Monday and has minimum 4 days
|
||||||
|
DateFormatter dateFormatter = DateFormatters.forPattern("YYYY-ww");
|
||||||
|
|
||||||
|
// first week of 2016 starts on Monday 2016-01-04 as previous week in 2016 has only 3 days
|
||||||
|
assertThat(DateFormatters.from(dateFormatter.parse("2016-01")) ,
|
||||||
|
equalTo(ZonedDateTime.of(2016,01,04, 0,0,0,0,ZoneOffset.UTC)));
|
||||||
|
|
||||||
|
// first week of 2015 starts on Monday 2014-12-29 because 4days belong to 2019
|
||||||
|
assertThat(DateFormatters.from(dateFormatter.parse("2015-01")) ,
|
||||||
|
equalTo(ZonedDateTime.of(2014,12,29, 0,0,0,0,ZoneOffset.UTC)));
|
||||||
|
|
||||||
|
|
||||||
|
// as per WeekFields.ISO first week starts on Monday and has minimum 4 days
|
||||||
|
dateFormatter = DateFormatters.forPattern("YYYY");
|
||||||
|
|
||||||
|
// first week of 2016 starts on Monday 2016-01-04 as previous week in 2016 has only 3 days
|
||||||
|
assertThat(DateFormatters.from(dateFormatter.parse("2016")) ,
|
||||||
|
equalTo(ZonedDateTime.of(2016,01,04, 0,0,0,0,ZoneOffset.UTC)));
|
||||||
|
|
||||||
|
// first week of 2015 starts on Monday 2014-12-29 because 4days belong to 2019
|
||||||
|
assertThat(DateFormatters.from(dateFormatter.parse("2015")) ,
|
||||||
|
equalTo(ZonedDateTime.of(2014,12,29, 0,0,0,0,ZoneOffset.UTC)));
|
||||||
|
}
|
||||||
|
|
||||||
// this is not in the duelling tests, because the epoch millis parser in joda time drops the milliseconds after the comma
|
// this is not in the duelling tests, because the epoch millis parser in joda time drops the milliseconds after the comma
|
||||||
// but is able to parse the rest
|
// but is able to parse the rest
|
||||||
// as this feature is supported it also makes sense to make it exact
|
// as this feature is supported it also makes sense to make it exact
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.common.time;
|
package org.elasticsearch.common.time;
|
||||||
|
|
||||||
import org.elasticsearch.ElasticsearchParseException;
|
import org.elasticsearch.ElasticsearchParseException;
|
||||||
|
import org.elasticsearch.bootstrap.JavaVersion;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
@ -50,6 +51,24 @@ public class JavaDateMathParserTests extends ESTestCase {
|
||||||
assertDateEquals(gotMillis, "297276785531", "297276785531");
|
assertDateEquals(gotMillis, "297276785531", "297276785531");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testWeekDates() {
|
||||||
|
assumeFalse("won't work in jdk8 " +
|
||||||
|
"because SPI mechanism is not looking at classpath - needs ISOCalendarDataProvider in jre's ext/libs",
|
||||||
|
JavaVersion.current().equals(JavaVersion.parse("8")));
|
||||||
|
|
||||||
|
DateFormatter formatter = DateFormatter.forPattern("YYYY-ww");
|
||||||
|
assertDateMathEquals(formatter.toDateMathParser(), "2016-01", "2016-01-04T23:59:59.999Z", 0, true, ZoneOffset.UTC);
|
||||||
|
|
||||||
|
formatter = DateFormatter.forPattern("YYYY");
|
||||||
|
assertDateMathEquals(formatter.toDateMathParser(), "2016", "2016-01-04T23:59:59.999Z", 0, true, ZoneOffset.UTC);
|
||||||
|
|
||||||
|
formatter = DateFormatter.forPattern("YYYY-ww");
|
||||||
|
assertDateMathEquals(formatter.toDateMathParser(), "2015-01", "2014-12-29T23:59:59.999Z", 0, true, ZoneOffset.UTC);
|
||||||
|
|
||||||
|
formatter = DateFormatter.forPattern("YYYY");
|
||||||
|
assertDateMathEquals(formatter.toDateMathParser(), "2015", "2014-12-29T23:59:59.999Z", 0, true, ZoneOffset.UTC);
|
||||||
|
}
|
||||||
|
|
||||||
public void testBasicDates() {
|
public void testBasicDates() {
|
||||||
assertDateMathEquals("2014-05-30", "2014-05-30T00:00:00.000");
|
assertDateMathEquals("2014-05-30", "2014-05-30T00:00:00.000");
|
||||||
assertDateMathEquals("2014-05-30T20", "2014-05-30T20:00:00.000");
|
assertDateMathEquals("2014-05-30T20", "2014-05-30T20:00:00.000");
|
||||||
|
|
|
@ -235,7 +235,7 @@ public class DateFieldMapperTests extends ESSingleNodeTestCase {
|
||||||
mapper.parse(new SourceToParse("test", "type", "1", BytesReference
|
mapper.parse(new SourceToParse("test", "type", "1", BytesReference
|
||||||
.bytes(XContentFactory.jsonBuilder()
|
.bytes(XContentFactory.jsonBuilder()
|
||||||
.startObject()
|
.startObject()
|
||||||
.field("field", "Mi., 06 Dez. 2000 02:55:00 -0800")
|
.field("field", "Mi, 06 Dez 2000 02:55:00 -0800")
|
||||||
.endObject()),
|
.endObject()),
|
||||||
XContentType.JSON));
|
XContentType.JSON));
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,12 +213,12 @@ public class JodaCompatibleZonedDateTimeTests extends ESTestCase {
|
||||||
|
|
||||||
public void testWeekOfWeekyear() {
|
public void testWeekOfWeekyear() {
|
||||||
assertMethodDeprecation(() -> assertThat(javaTime.getWeekOfWeekyear(), equalTo(jodaTime.getWeekOfWeekyear())),
|
assertMethodDeprecation(() -> assertThat(javaTime.getWeekOfWeekyear(), equalTo(jodaTime.getWeekOfWeekyear())),
|
||||||
"getWeekOfWeekyear()", "get(WeekFields.ISO.weekOfWeekBasedYear())");
|
"getWeekOfWeekyear()", "get(DateFormatters.WEEK_FIELDS.weekOfWeekBasedYear())");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testWeekyear() {
|
public void testWeekyear() {
|
||||||
assertMethodDeprecation(() -> assertThat(javaTime.getWeekyear(), equalTo(jodaTime.getWeekyear())),
|
assertMethodDeprecation(() -> assertThat(javaTime.getWeekyear(), equalTo(jodaTime.getWeekyear())),
|
||||||
"getWeekyear()", "get(WeekFields.ISO.weekBasedYear())");
|
"getWeekyear()", "get(DateFormatters.WEEK_FIELDS.weekBasedYear())");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testYearOfCentury() {
|
public void testYearOfCentury() {
|
||||||
|
|
|
@ -1678,21 +1678,21 @@ public class SearchQueryIT extends ESIntegTestCase {
|
||||||
.endObject().endObject().endObject()));
|
.endObject().endObject().endObject()));
|
||||||
|
|
||||||
indexRandom(true,
|
indexRandom(true,
|
||||||
client().prepareIndex("test", "type1", "1").setSource("date_field", "Mi., 06 Dez. 2000 02:55:00 -0800"),
|
client().prepareIndex("test", "type1", "1").setSource("date_field", "Mi, 06 Dez 2000 02:55:00 -0800"),
|
||||||
client().prepareIndex("test", "type1", "2").setSource("date_field", "Do., 07 Dez. 2000 02:55:00 -0800")
|
client().prepareIndex("test", "type1", "2").setSource("date_field", "Do, 07 Dez 2000 02:55:00 -0800")
|
||||||
);
|
);
|
||||||
|
|
||||||
SearchResponse searchResponse = client().prepareSearch("test")
|
SearchResponse searchResponse = client().prepareSearch("test")
|
||||||
.setQuery(QueryBuilders.rangeQuery("date_field")
|
.setQuery(QueryBuilders.rangeQuery("date_field")
|
||||||
.gte("Di., 05 Dez. 2000 02:55:00 -0800")
|
.gte("Di, 05 Dez 2000 02:55:00 -0800")
|
||||||
.lte("Do., 07 Dez. 2000 00:00:00 -0800"))
|
.lte("Do, 07 Dez 2000 00:00:00 -0800"))
|
||||||
.get();
|
.get();
|
||||||
assertHitCount(searchResponse, 1L);
|
assertHitCount(searchResponse, 1L);
|
||||||
|
|
||||||
searchResponse = client().prepareSearch("test")
|
searchResponse = client().prepareSearch("test")
|
||||||
.setQuery(QueryBuilders.rangeQuery("date_field")
|
.setQuery(QueryBuilders.rangeQuery("date_field")
|
||||||
.gte("Di., 05 Dez. 2000 02:55:00 -0800")
|
.gte("Di, 05 Dez 2000 02:55:00 -0800")
|
||||||
.lte("Fr., 08 Dez. 2000 00:00:00 -0800"))
|
.lte("Fr, 08 Dez 2000 00:00:00 -0800"))
|
||||||
.get();
|
.get();
|
||||||
assertHitCount(searchResponse, 2L);
|
assertHitCount(searchResponse, 2L);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,23 +17,11 @@ import static org.hamcrest.Matchers.startsWith;
|
||||||
/**
|
/**
|
||||||
* Due to changes in JDK9 where locale data is used from CLDR, the licence message will differ in jdk 8 and jdk9+
|
* Due to changes in JDK9 where locale data is used from CLDR, the licence message will differ in jdk 8 and jdk9+
|
||||||
* https://openjdk.java.net/jeps/252
|
* https://openjdk.java.net/jeps/252
|
||||||
|
* We run ES with -Djava.locale.providers=SPI,COMPAT and same option has to be applied when running this test from IDE
|
||||||
*/
|
*/
|
||||||
public class LicenseServiceTests extends ESTestCase {
|
public class LicenseServiceTests extends ESTestCase {
|
||||||
|
|
||||||
public void testLogExpirationWarningOnJdk9AndNewer() {
|
public void testLogExpirationWarning() {
|
||||||
assumeTrue("this is for JDK9+", JavaVersion.current().compareTo(JavaVersion.parse("9")) >= 0);
|
|
||||||
|
|
||||||
long time = LocalDate.of(2018, 11, 15).atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli();
|
|
||||||
final boolean expired = randomBoolean();
|
|
||||||
final String message = LicenseService.buildExpirationMessage(time, expired).toString();
|
|
||||||
if (expired) {
|
|
||||||
assertThat(message, startsWith("LICENSE [EXPIRED] ON [THU, NOV 15, 2018].\n"));
|
|
||||||
} else {
|
|
||||||
assertThat(message, startsWith("License [will expire] on [Thu, Nov 15, 2018].\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testLogExpirationWarningOnJdk8() {
|
|
||||||
assumeTrue("this is for JDK8 only", JavaVersion.current().equals(JavaVersion.parse("8")));
|
assumeTrue("this is for JDK8 only", JavaVersion.current().equals(JavaVersion.parse("8")));
|
||||||
|
|
||||||
long time = LocalDate.of(2018, 11, 15).atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli();
|
long time = LocalDate.of(2018, 11, 15).atStartOfDay(ZoneOffset.UTC).toInstant().toEpochMilli();
|
||||||
|
@ -45,5 +33,4 @@ public class LicenseServiceTests extends ESTestCase {
|
||||||
assertThat(message, startsWith("License [will expire] on [Thursday, November 15, 2018].\n"));
|
assertThat(message, startsWith("License [will expire] on [Thursday, November 15, 2018].\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -430,7 +430,6 @@ public class TimestampFormatFinderTests extends FileStructureTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGuessIsDayFirstFromLocale() {
|
public void testGuessIsDayFirstFromLocale() {
|
||||||
|
|
||||||
TimestampFormatFinder timestampFormatFinder = new TimestampFormatFinder(explanation, true, true, true, NOOP_TIMEOUT_CHECKER);
|
TimestampFormatFinder timestampFormatFinder = new TimestampFormatFinder(explanation, true, true, true, NOOP_TIMEOUT_CHECKER);
|
||||||
|
|
||||||
// Locale fallback is the only way to decide
|
// Locale fallback is the only way to decide
|
||||||
|
|
|
@ -10,14 +10,12 @@ import org.elasticsearch.common.io.stream.StreamInput;
|
||||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.time.LocalDateTime;
|
import java.time.DayOfWeek;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.temporal.ChronoField;
|
import java.time.temporal.ChronoField;
|
||||||
import java.util.Calendar;
|
import java.time.temporal.WeekFields;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class NonIsoDateTimeProcessor extends BaseDateTimeProcessor {
|
public class NonIsoDateTimeProcessor extends BaseDateTimeProcessor {
|
||||||
|
@ -30,15 +28,7 @@ public class NonIsoDateTimeProcessor extends BaseDateTimeProcessor {
|
||||||
return dayOfWeek == 8 ? 1 : dayOfWeek;
|
return dayOfWeek == 8 ? 1 : dayOfWeek;
|
||||||
}),
|
}),
|
||||||
WEEK_OF_YEAR(zdt -> {
|
WEEK_OF_YEAR(zdt -> {
|
||||||
// by ISO 8601 standard, the first week of a year is the first week with a majority (4 or more) of its days in January.
|
return zdt.get(WeekFields.of(DayOfWeek.SUNDAY, 1).weekOfWeekBasedYear());
|
||||||
// Other Locales may have their own standards (see Arabic or Japanese calendars).
|
|
||||||
LocalDateTime ld = zdt.toLocalDateTime();
|
|
||||||
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(zdt.getZone()), Locale.ROOT);
|
|
||||||
cal.clear();
|
|
||||||
cal.set(ld.get(ChronoField.YEAR), ld.get(ChronoField.MONTH_OF_YEAR) - 1, ld.get(ChronoField.DAY_OF_MONTH),
|
|
||||||
ld.get(ChronoField.HOUR_OF_DAY), ld.get(ChronoField.MINUTE_OF_HOUR), ld.get(ChronoField.SECOND_OF_MINUTE));
|
|
||||||
|
|
||||||
return cal.get(Calendar.WEEK_OF_YEAR);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
private final Function<ZonedDateTime, Integer> apply;
|
private final Function<ZonedDateTime, Integer> apply;
|
||||||
|
|
|
@ -17,7 +17,6 @@ import static org.elasticsearch.xpack.sql.util.DateUtils.UTC;
|
||||||
|
|
||||||
public class NonIsoDateTimeProcessorTests extends AbstractSqlWireSerializingTestCase<NonIsoDateTimeProcessor> {
|
public class NonIsoDateTimeProcessorTests extends AbstractSqlWireSerializingTestCase<NonIsoDateTimeProcessor> {
|
||||||
|
|
||||||
|
|
||||||
public static NonIsoDateTimeProcessor randomNonISODateTimeProcessor() {
|
public static NonIsoDateTimeProcessor randomNonISODateTimeProcessor() {
|
||||||
return new NonIsoDateTimeProcessor(randomFrom(NonIsoDateTimeExtractor.values()), UTC);
|
return new NonIsoDateTimeProcessor(randomFrom(NonIsoDateTimeExtractor.values()), UTC);
|
||||||
}
|
}
|
||||||
|
@ -45,6 +44,8 @@ public class NonIsoDateTimeProcessorTests extends AbstractSqlWireSerializingTest
|
||||||
|
|
||||||
public void testNonISOWeekOfYearInUTC() {
|
public void testNonISOWeekOfYearInUTC() {
|
||||||
NonIsoDateTimeProcessor proc = new NonIsoDateTimeProcessor(NonIsoDateTimeExtractor.WEEK_OF_YEAR, UTC);
|
NonIsoDateTimeProcessor proc = new NonIsoDateTimeProcessor(NonIsoDateTimeExtractor.WEEK_OF_YEAR, UTC);
|
||||||
|
// 1 Jan 1988 is Friday - under Sunday,1 rule it is the first week of the year (under ISO rule it would be 53 of the previous year
|
||||||
|
// hence the 5th Jan 1988 Tuesday is the second week of a year
|
||||||
assertEquals(2, proc.process(dateTime(568372930000L))); //1988-01-05T09:22:10Z[UTC]
|
assertEquals(2, proc.process(dateTime(568372930000L))); //1988-01-05T09:22:10Z[UTC]
|
||||||
assertEquals(6, proc.process(dateTime(981278530000L))); //2001-02-04T09:22:10Z[UTC]
|
assertEquals(6, proc.process(dateTime(981278530000L))); //2001-02-04T09:22:10Z[UTC]
|
||||||
assertEquals(7, proc.process(dateTime(224241730000L))); //1977-02-08T09:22:10Z[UTC]
|
assertEquals(7, proc.process(dateTime(224241730000L))); //1977-02-08T09:22:10Z[UTC]
|
||||||
|
|
Loading…
Reference in New Issue