8247781: Day periods support

Reviewed-by: scolebourne, rriggs, joehw
This commit is contained in:
Naoto Sato 2020-11-16 23:12:45 +00:00
parent 0357db3581
commit bf84dac4cf
20 changed files with 1155 additions and 203 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -854,32 +854,32 @@ public class TCKDateTimeParseResolver {
@DataProvider(name="resolveAmPm")
Object[][] data_resolveAmPm() {
return new Object[][]{
{STRICT, 0, 0},
{STRICT, 1, 1},
{STRICT, -1, null},
{STRICT, 2, null},
{STRICT, 0, null, 0},
{STRICT, 1, null, 1},
{STRICT, -1, null, null},
{STRICT, 2, null, null},
{SMART, 0, 0},
{SMART, 1, 1},
{SMART, -1, null},
{SMART, 2, null},
{SMART, 0, LocalTime.of(6, 0), 0},
{SMART, 1, LocalTime.of(18, 0), 1},
{SMART, -1, null, null},
{SMART, 2, null, null},
{LENIENT, 0, 0},
{LENIENT, 1, 1},
{LENIENT, -1, -1},
{LENIENT, 2, 2},
{LENIENT, 0, LocalTime.of(6, 0), 0},
{LENIENT, 1, LocalTime.of(18, 0), 1},
{LENIENT, -1, LocalTime.of(18, 0), 1},
{LENIENT, 2, LocalTime.of(6, 0), 0},
};
}
@Test(dataProvider="resolveAmPm")
public void test_resolveAmPm(ResolverStyle style, long value, Integer expectedValue) {
public void test_resolveAmPm(ResolverStyle style, long value, LocalTime expectedTime, Integer expectedValue) {
String str = Long.toString(value);
DateTimeFormatter f = new DateTimeFormatterBuilder().appendValue(AMPM_OF_DAY).toFormatter();
if (expectedValue != null) {
TemporalAccessor accessor = f.withResolverStyle(style).parse(str);
assertEquals(accessor.query(TemporalQueries.localDate()), null);
assertEquals(accessor.query(TemporalQueries.localTime()), null);
assertEquals(accessor.query(TemporalQueries.localTime()), expectedTime);
assertEquals(accessor.isSupported(AMPM_OF_DAY), true);
assertEquals(accessor.getLong(AMPM_OF_DAY), expectedValue.longValue());
} else {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -59,29 +59,38 @@
*/
package test.java.time.format;
import static java.time.format.DateTimeFormatter.ISO_LOCAL_TIME;
import static java.time.temporal.ChronoField.DAY_OF_MONTH;
import static java.time.temporal.ChronoField.DAY_OF_WEEK;
import static java.time.temporal.ChronoField.HOUR_OF_DAY;
import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
import static java.time.temporal.ChronoField.YEAR;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.fail;
import java.text.ParsePosition;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Period;
import java.time.YearMonth;
import java.time.ZoneOffset;
import java.time.chrono.Chronology;
import java.time.chrono.IsoChronology;
import java.time.chrono.JapaneseChronology;
import java.time.chrono.MinguoChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.format.FormatStyle;
import java.time.format.ResolverStyle;
import java.time.format.SignStyle;
import java.time.format.TextStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.TemporalUnit;
import java.time.temporal.ValueRange;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@ -526,6 +535,360 @@ public class TestDateTimeFormatterBuilder {
builder.appendZoneText(null);
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
@Test
public void test_appendDayPeriodText_1arg() throws Exception {
builder.appendDayPeriodText(TextStyle.FULL);
DateTimeFormatter f = builder.toFormatter();
assertEquals(f.toString(), "DayPeriod(FULL)");
}
@Test(expectedExceptions=NullPointerException.class)
public void test_appendDayPeriodText_1arg_nullText() throws Exception {
builder.appendDayPeriodText(null);
}
@DataProvider(name="dayPeriodFormat")
Object[][] data_dayPeriodFormat() {
return new Object[][] {
{0, 0, TextStyle.FULL, Locale.US, "midnight"},
{0, 1, TextStyle.FULL, Locale.US, "at night"},
{6, 0, TextStyle.FULL, Locale.US, "in the morning"},
{12, 0, TextStyle.FULL, Locale.US, "noon"},
{12, 1, TextStyle.FULL, Locale.US, "in the afternoon"},
{18, 0, TextStyle.FULL, Locale.US, "in the evening"},
{22, 0, TextStyle.FULL, Locale.US, "at night"},
{0, 0, TextStyle.FULL, Locale.JAPAN, "\u771f\u591c\u4e2d"},
{0, 1, TextStyle.FULL, Locale.JAPAN, "\u591c\u4e2d"},
{6, 0, TextStyle.FULL, Locale.JAPAN, "\u671d"},
{12, 0, TextStyle.FULL, Locale.JAPAN, "\u6b63\u5348"},
{12, 1, TextStyle.FULL, Locale.JAPAN, "\u663c"},
{18, 0, TextStyle.FULL, Locale.JAPAN, "\u5915\u65b9"},
{19, 0, TextStyle.FULL, Locale.JAPAN, "\u591c"},
{23, 0, TextStyle.FULL, Locale.JAPAN, "\u591c\u4e2d"},
{0, 0, TextStyle.NARROW, Locale.US, "mi"},
{0, 1, TextStyle.NARROW, Locale.US, "at night"},
{6, 0, TextStyle.NARROW, Locale.US, "in the morning"},
{12, 0, TextStyle.NARROW, Locale.US, "n"},
{12, 1, TextStyle.NARROW, Locale.US, "in the afternoon"},
{18, 0, TextStyle.NARROW, Locale.US, "in the evening"},
{22, 0, TextStyle.NARROW, Locale.US, "at night"},
{0, 0, TextStyle.NARROW, Locale.JAPAN, "\u771f\u591c\u4e2d"},
{0, 1, TextStyle.NARROW, Locale.JAPAN, "\u591c\u4e2d"},
{6, 0, TextStyle.NARROW, Locale.JAPAN, "\u671d"},
{12, 0, TextStyle.NARROW, Locale.JAPAN, "\u6b63\u5348"},
{12, 1, TextStyle.NARROW, Locale.JAPAN, "\u663c"},
{18, 0, TextStyle.NARROW, Locale.JAPAN, "\u5915\u65b9"},
{19, 0, TextStyle.NARROW, Locale.JAPAN, "\u591c"},
{23, 0, TextStyle.NARROW, Locale.JAPAN, "\u591c\u4e2d"},
};
}
@Test (dataProvider="dayPeriodFormat")
public void test_dayPeriodFormat(int hod, int moh, TextStyle ts, Locale l, String expected) throws Exception {
builder.appendDayPeriodText(ts);
LocalTime t = LocalTime.of(hod, moh);
DateTimeFormatter f = builder.toFormatter().withLocale(l);
assertEquals(f.format(t), expected);
}
@DataProvider(name="dayPeriodParse")
Object[][] data_dayPeriodParse() {
return new Object[][] {
{TextStyle.FULL, Locale.US, 0, 0, "midnight"},
{TextStyle.FULL, Locale.US, 1, 30, "at night"},
{TextStyle.FULL, Locale.US, 6, 0, "AM"},
{TextStyle.FULL, Locale.US, 9, 0, "in the morning"},
{TextStyle.FULL, Locale.US, 12, 0, "noon"},
{TextStyle.FULL, Locale.US, 15, 0, "in the afternoon"},
{TextStyle.FULL, Locale.US, 18, 0, "PM"},
{TextStyle.FULL, Locale.US, 19, 30, "in the evening"},
{TextStyle.FULL, Locale.JAPAN, 0, 0, "\u771f\u591c\u4e2d"},
{TextStyle.FULL, Locale.JAPAN, 1, 30, "\u591c\u4e2d"},
{TextStyle.FULL, Locale.JAPAN, 6, 0, "\u5348\u524d"},
{TextStyle.FULL, Locale.JAPAN, 8, 0, "\u671d"},
{TextStyle.FULL, Locale.JAPAN, 12, 0, "\u6b63\u5348"},
{TextStyle.FULL, Locale.JAPAN, 14, 0, "\u663c"},
{TextStyle.FULL, Locale.JAPAN, 17, 30, "\u5915\u65b9"},
{TextStyle.FULL, Locale.JAPAN, 18, 0, "\u5348\u5f8c"},
{TextStyle.FULL, Locale.JAPAN, 21, 0, "\u591c"},
{TextStyle.NARROW, Locale.US, 0, 0, "mi"},
{TextStyle.NARROW, Locale.US, 1, 30, "at night"},
{TextStyle.NARROW, Locale.US, 6, 0, "a"},
{TextStyle.NARROW, Locale.US, 9, 0, "in the morning"},
{TextStyle.NARROW, Locale.US, 12, 0, "n"},
{TextStyle.NARROW, Locale.US, 15, 0, "in the afternoon"},
{TextStyle.NARROW, Locale.US, 18, 0, "p"},
{TextStyle.NARROW, Locale.US, 19, 30, "in the evening"},
{TextStyle.NARROW, Locale.JAPAN, 0, 0, "\u771f\u591c\u4e2d"},
{TextStyle.NARROW, Locale.JAPAN, 1, 30, "\u591c\u4e2d"},
{TextStyle.NARROW, Locale.JAPAN, 6, 0, "\u5348\u524d"},
{TextStyle.NARROW, Locale.JAPAN, 8, 0, "\u671d"},
{TextStyle.NARROW, Locale.JAPAN, 12, 0, "\u6b63\u5348"},
{TextStyle.NARROW, Locale.JAPAN, 14, 0, "\u663c"},
{TextStyle.NARROW, Locale.JAPAN, 17, 30, "\u5915\u65b9"},
{TextStyle.NARROW, Locale.JAPAN, 18, 0, "\u5348\u5f8c"},
{TextStyle.NARROW, Locale.JAPAN, 21, 0, "\u591c"},
};
}
@Test (dataProvider="dayPeriodParse")
public void test_dayPeriodParse(TextStyle ts, Locale l, long hod, long moh, String dayPeriod) throws Exception {
builder.appendDayPeriodText(ts);
DateTimeFormatter f = builder.toFormatter().withLocale(l);
var p = f.parse(dayPeriod);
assertEquals(p.getLong(HOUR_OF_DAY), hod);
assertEquals(p.getLong(MINUTE_OF_HOUR), moh);
}
@DataProvider(name="dayPeriodParsePattern")
Object[][] data_dayPeriodParsePattern() {
return new Object[][] {
{"H B", "23 at night", 23},
{"H B", "3 at night", 3},
{"K B", "11 at night", 23},
{"K B", "3 at night", 3},
{"K B", "11 in the morning", 11},
{"h B", "11 at night", 23},
{"h B", "3 at night", 3},
{"h B", "11 in the morning", 11},
{"a", "AM", 6},
{"a", "PM", 18},
};
}
@Test (dataProvider="dayPeriodParsePattern")
public void test_dayPeriodParsePattern(String pattern, String hourDayPeriod, long expected) throws Exception {
builder.appendPattern(pattern);
DateTimeFormatter f = builder.toFormatter().withLocale(Locale.US);
var p = f.parse(hourDayPeriod);
assertEquals(p.getLong(HOUR_OF_DAY), expected);
}
@DataProvider(name="dayPeriodParseMidnight")
Object[][] data_dayPeriodParseMidnight() {
return new Object[][] {
{"u-M-d H:m B", "2020-11-07 00:00 midnight", 7, 0},
{"u-M-d H:m B", "2020-11-07 24:00 midnight", 8, 0},
};
}
@Test (dataProvider="dayPeriodParseMidnight")
public void test_dayPeriodParseMidnight(String pattern, String dateTime, long expectedDOM, long expectedHOD) throws Exception {
builder.appendPattern(pattern);
DateTimeFormatter f = builder.toFormatter().withLocale(Locale.US);
var p = f.parse(dateTime);
assertEquals(p.getLong(DAY_OF_MONTH), expectedDOM);
assertEquals(p.getLong(HOUR_OF_DAY), expectedHOD);
}
@DataProvider(name="dayPeriodParseInvalid")
Object[][] data_dayPeriodParseInvalid() {
return new Object[][] {
{TextStyle.FULL, ResolverStyle.SMART, Locale.US, "00:01 midnight", "00:00"},
{TextStyle.FULL, ResolverStyle.SMART, Locale.US, "06:01 at night", "21:00-06:00"},
{TextStyle.FULL, ResolverStyle.SMART, Locale.US, "05:59 in the morning", "06:00-12:00"},
{TextStyle.FULL, ResolverStyle.SMART, Locale.US, "11:59 noon", "12:00"},
{TextStyle.FULL, ResolverStyle.SMART, Locale.US, "18:00 in the afternoon", "12:00-18:00"},
{TextStyle.FULL, ResolverStyle.SMART, Locale.US, "17:59 in the evening", "18:00-21:00"},
{TextStyle.NARROW, ResolverStyle.SMART, Locale.US, "00:01 mi", "00:00"},
{TextStyle.NARROW, ResolverStyle.SMART, Locale.US, "06:01 at night", "21:00-06:00"},
{TextStyle.NARROW, ResolverStyle.SMART, Locale.US, "05:59 in the morning", "06:00-12:00"},
{TextStyle.NARROW, ResolverStyle.SMART, Locale.US, "11:59 n", "12:00"},
{TextStyle.NARROW, ResolverStyle.SMART, Locale.US, "18:00 in the afternoon", "12:00-18:00"},
{TextStyle.NARROW, ResolverStyle.SMART, Locale.US, "17:59 in the evening", "18:00-21:00"},
{TextStyle.FULL, ResolverStyle.SMART, Locale.JAPAN, "00:01 \u771f\u591c\u4e2d", "00:00"},
{TextStyle.FULL, ResolverStyle.SMART, Locale.JAPAN, "04:00 \u591c\u4e2d", "23:00-04:00"},
{TextStyle.FULL, ResolverStyle.SMART, Locale.JAPAN, "03:59 \u671d", "04:00-12:00"},
{TextStyle.FULL, ResolverStyle.SMART, Locale.JAPAN, "12:01 \u6b63\u5348", "12:00"},
{TextStyle.FULL, ResolverStyle.SMART, Locale.JAPAN, "16:00 \u663c", "12:00-16:00"},
{TextStyle.FULL, ResolverStyle.SMART, Locale.JAPAN, "19:01 \u5915\u65b9", "16:00-19:00"},
{TextStyle.FULL, ResolverStyle.SMART, Locale.JAPAN, "23:00 \u591c", "19:00-23:00"},
{TextStyle.NARROW, ResolverStyle.SMART, Locale.JAPAN, "00:01 \u771f\u591c\u4e2d", "00:00"},
{TextStyle.NARROW, ResolverStyle.SMART, Locale.JAPAN, "04:00 \u591c\u4e2d", "23:00-04:00"},
{TextStyle.NARROW, ResolverStyle.SMART, Locale.JAPAN, "03:59 \u671d", "04:00-12:00"},
{TextStyle.NARROW, ResolverStyle.SMART, Locale.JAPAN, "12:01 \u6b63\u5348", "12:00"},
{TextStyle.NARROW, ResolverStyle.SMART, Locale.JAPAN, "16:00 \u663c", "12:00-16:00"},
{TextStyle.NARROW, ResolverStyle.SMART, Locale.JAPAN, "19:01 \u5915\u65b9", "16:00-19:00"},
{TextStyle.NARROW, ResolverStyle.SMART, Locale.JAPAN, "23:00 \u591c", "19:00-23:00"},
{TextStyle.FULL, ResolverStyle.LENIENT, Locale.US, "00:01 midnight", "00:00"},
{TextStyle.FULL, ResolverStyle.LENIENT, Locale.US, "06:01 at night", "21:00-06:00"},
{TextStyle.FULL, ResolverStyle.LENIENT, Locale.US, "05:59 in the morning", "06:00-12:00"},
{TextStyle.FULL, ResolverStyle.LENIENT, Locale.US, "11:59 noon", "12:00"},
{TextStyle.FULL, ResolverStyle.LENIENT, Locale.US, "18:00 in the afternoon", "12:00-18:00"},
{TextStyle.FULL, ResolverStyle.LENIENT, Locale.US, "17:59 in the evening", "18:00-21:00"},
{TextStyle.NARROW, ResolverStyle.LENIENT, Locale.US, "00:01 mi", "00:00"},
{TextStyle.NARROW, ResolverStyle.LENIENT, Locale.US, "06:01 at night", "21:00-06:00"},
{TextStyle.NARROW, ResolverStyle.LENIENT, Locale.US, "05:59 in the morning", "06:00-12:00"},
{TextStyle.NARROW, ResolverStyle.LENIENT, Locale.US, "11:59 n", "12:00"},
{TextStyle.NARROW, ResolverStyle.LENIENT, Locale.US, "18:00 in the afternoon", "12:00-18:00"},
{TextStyle.NARROW, ResolverStyle.LENIENT, Locale.US, "17:59 in the evening", "18:00-21:00"},
{TextStyle.FULL, ResolverStyle.LENIENT, Locale.JAPAN, "00:01 \u771f\u591c\u4e2d", "00:00"},
{TextStyle.FULL, ResolverStyle.LENIENT, Locale.JAPAN, "04:00 \u591c\u4e2d", "23:00-04:00"},
{TextStyle.FULL, ResolverStyle.LENIENT, Locale.JAPAN, "03:59 \u671d", "04:00-12:00"},
{TextStyle.FULL, ResolverStyle.LENIENT, Locale.JAPAN, "12:01 \u6b63\u5348", "12:00"},
{TextStyle.FULL, ResolverStyle.LENIENT, Locale.JAPAN, "16:00 \u663c", "12:00-16:00"},
{TextStyle.FULL, ResolverStyle.LENIENT, Locale.JAPAN, "19:01 \u5915\u65b9", "16:00-19:00"},
{TextStyle.FULL, ResolverStyle.LENIENT, Locale.JAPAN, "23:00 \u591c", "19:00-23:00"},
{TextStyle.NARROW, ResolverStyle.LENIENT, Locale.JAPAN, "00:01 \u771f\u591c\u4e2d", "00:00"},
{TextStyle.NARROW, ResolverStyle.LENIENT, Locale.JAPAN, "04:00 \u591c\u4e2d", "23:00-04:00"},
{TextStyle.NARROW, ResolverStyle.LENIENT, Locale.JAPAN, "03:59 \u671d", "04:00-12:00"},
{TextStyle.NARROW, ResolverStyle.LENIENT, Locale.JAPAN, "12:01 \u6b63\u5348", "12:00"},
{TextStyle.NARROW, ResolverStyle.LENIENT, Locale.JAPAN, "16:00 \u663c", "12:00-16:00"},
{TextStyle.NARROW, ResolverStyle.LENIENT, Locale.JAPAN, "19:01 \u5915\u65b9", "16:00-19:00"},
{TextStyle.NARROW, ResolverStyle.LENIENT, Locale.JAPAN, "23:00 \u591c", "19:00-23:00"},
};
}
@Test (dataProvider="dayPeriodParseInvalid")
public void test_dayPeriodParseInvalid(TextStyle ts, ResolverStyle rs, Locale l, String dayPeriod, String periodRange) throws Exception {
try {
builder.append(ISO_LOCAL_TIME).appendLiteral(' ').appendDayPeriodText(ts)
.toFormatter()
.withLocale(l)
.parse(dayPeriod);
if (rs != ResolverStyle.LENIENT) {
throw new RuntimeException("DateTimeParseException should be thrown");
}
} catch (DateTimeParseException e) {
assertEquals(e.getCause().getMessage(),
"Conflict found: Resolved time " + dayPeriod.substring(0, 5) + " conflicts with " +
"DayPeriod(" + periodRange + ")");
}
}
@DataProvider(name="dayPeriodParsePatternInvalid")
Object[][] data_dayPeriodParsePatternInvalid() {
return new Object[][] {
{"H B", ResolverStyle.SMART, "47 at night", 23, null},
{"H B", ResolverStyle.SMART, "51 at night", 3, null},
{"H B", ResolverStyle.SMART, "-2 at night", 22, null},
{"K B", ResolverStyle.SMART, "59 at night", 23, null},
{"K B", ResolverStyle.SMART, "51 at night", 3, null},
{"K B", ResolverStyle.SMART, "59 in the morning", 11, null},
{"K B", ResolverStyle.SMART, "-2 in the morning", 22, null},
{"h B", ResolverStyle.SMART, "59 at night", 23, null},
{"h B", ResolverStyle.SMART, "51 at night", 3, null},
{"h B", ResolverStyle.SMART, "59 in the morning", 11, null},
{"h B", ResolverStyle.SMART, "-2 in the morning", 22, null},
{"H B", ResolverStyle.LENIENT, "47 at night", 23, Period.ofDays(1)},
{"H B", ResolverStyle.LENIENT, "51 at night", 3, Period.ofDays(2)},
{"H B", ResolverStyle.LENIENT, "-2 at night", 22, Period.ofDays(-1)},
{"K B", ResolverStyle.LENIENT, "59 at night", 23, Period.ofDays(2)},
{"K B", ResolverStyle.LENIENT, "51 at night", 3, Period.ofDays(2)},
{"K B", ResolverStyle.LENIENT, "59 in the morning", 11, Period.ofDays(2)},
{"K B", ResolverStyle.LENIENT, "-2 in the morning", 22, Period.ofDays(-1)},
{"h B", ResolverStyle.LENIENT, "59 at night", 23, Period.ofDays(2)},
{"h B", ResolverStyle.LENIENT, "51 at night", 3, Period.ofDays(2)},
{"h B", ResolverStyle.LENIENT, "59 in the morning", 11, Period.ofDays(2)},
{"h B", ResolverStyle.LENIENT, "-2 in the morning", 22, Period.ofDays(-1)},
};
}
@Test (dataProvider="dayPeriodParsePatternInvalid")
public void test_dayPeriodParsePatternInvalid(String pattern, ResolverStyle rs, String hourDayPeriod, long expected, Period expectedExcessDays) throws Exception {
try {
builder.appendPattern(pattern);
DateTimeFormatter f = builder.toFormatter().withLocale(Locale.US).withResolverStyle(rs);
var p = f.parse(hourDayPeriod);
if (rs != ResolverStyle.LENIENT) {
throw new RuntimeException("DateTimeParseException should be thrown");
}
assertEquals(p.getLong(HOUR_OF_DAY), expected);
assertEquals(p.query(DateTimeFormatter.parsedExcessDays()), expectedExcessDays);
} catch (DateTimeParseException e) {
// exception successfully thrown
}
}
@Test (expectedExceptions = DateTimeParseException.class)
public void test_dayPeriodParseStrictNoTime() {
builder.appendPattern("B");
DateTimeFormatter f = builder.toFormatter().withLocale(Locale.US).withResolverStyle(ResolverStyle.STRICT);
LocalTime.parse("at night", f);
}
@Test
public void test_dayPeriodUserFieldResolution() {
var dtf = builder
.appendValue(new TemporalField() {
@Override
public TemporalUnit getBaseUnit() {
return null;
}
@Override
public TemporalUnit getRangeUnit() {
return null;
}
@Override
public ValueRange range() {
return null;
}
@Override
public boolean isDateBased() {
return false;
}
@Override
public boolean isTimeBased() {
return false;
}
@Override
public boolean isSupportedBy(TemporalAccessor temporal) {
return false;
}
@Override
public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
return null;
}
@Override
public long getFrom(TemporalAccessor temporal) {
return 0;
}
@Override
public <R extends Temporal> R adjustInto(R temporal, long newValue) {
return null;
}
@Override
public TemporalAccessor resolve(
Map<TemporalField, Long> fieldValues,
TemporalAccessor partialTemporal,
ResolverStyle resolverStyle) {
fieldValues.remove(this);
fieldValues.put(ChronoField.HOUR_OF_DAY, 6L);
return null;
}
},
1)
.appendPattern(" B")
.toFormatter()
.withLocale(Locale.US);
assertEquals((long)dtf.parse("0 in the morning").getLong(ChronoField.HOUR_OF_DAY), 6L);
try {
dtf.parse("0 at night");
fail("DateTimeParseException should be thrown");
} catch (DateTimeParseException e) {
// success
}
}
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
@ -792,6 +1155,10 @@ public class TestDateTimeFormatterBuilder {
{"w", "Localized(WeekOfWeekBasedYear,1)"},
{"ww", "Localized(WeekOfWeekBasedYear,2)"},
{"W", "Localized(WeekOfMonth,1)"},
{"B", "DayPeriod(SHORT)"},
{"BBBB", "DayPeriod(FULL)"},
{"BBBBB", "DayPeriod(NARROW)"},
};
}
@ -867,6 +1234,10 @@ public class TestDateTimeFormatterBuilder {
{"www"},
{"WW"},
{"BB"},
{"BBB"},
{"BBBBBB"},
};
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -22,12 +22,12 @@
*/
/*
* @test
* @bug 8209175
* @summary Checks the 'B' character added in the CLDR date-time patterns is
* @bug 8209175 8247781
* @summary Checks the 'B' character added in the CLDR date-time patterns is no longer
* getting resolved with 'a' character (am/pm strings) for burmese locale.
* This test case assumes that the 'B' character is added in CLDRv33 update
* for burmese locale in the time patterns. Since it is not supported by
* DateTimeFormatter it is replaced with the 'a' while CLDR resource
* for burmese locale in the time patterns. Since it is supported by
* DateTimeFormatter it should not be replaced with the 'a' while CLDR resource
* conversion.
* @modules jdk.localedata
*/
@ -56,10 +56,11 @@ public class TestDayPeriodWithDTF {
@DataProvider(name = "timePatternData")
Object[][] timePatternData() {
return new Object[][] {
// these messages are for day periods in Burmese.
{FORMAT_SHORT_BURMESE, LOCAL_TIME_AM, "\u1014\u1036\u1014\u1000\u103A 10:10"},
{FORMAT_SHORT_BURMESE, LOCAL_TIME_PM, "\u100A\u1014\u1031 12:12"},
{FORMAT_SHORT_BURMESE, LOCAL_TIME_PM, "\u1014\u1031\u1037\u101c\u101a\u103a 12:12"},
{FORMAT_MEDIUM_BURMESE, LOCAL_TIME_AM, "\u1014\u1036\u1014\u1000\u103A 10:10:10"},
{FORMAT_MEDIUM_BURMESE, LOCAL_TIME_PM, "\u100A\u1014\u1031 12:12:12"},
{FORMAT_MEDIUM_BURMESE, LOCAL_TIME_PM, "\u1014\u1031\u1037\u101c\u101a\u103a 12:12:12"},
};
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,12 +23,14 @@
/*
* @test
* @bug 8007038
* @bug 8007038 8247781
* @summary Verify ArrayIndexOutOfBoundsException is not thrown on
* on calling localizedDateTime().print() with JapaneseChrono
* @modules java.base/sun.util.locale.provider
* @modules jdk.localedata
* @compile -XDignore.symbol.file Bug8007038.java
* @run main Bug8007038
* @run main/othervm -Djava.locale.providers=COMPAT Bug8007038 COMPAT
* @run main/othervm -Djava.locale.providers=CLDR Bug8007038 CLDR
*/
import java.util.*;
@ -88,11 +90,12 @@ public class Bug8007038 {
checkValueRange(calTypes[calIdx], DAY_OF_WEEK, SATURDAY+1, LONG, testLocs[locIdx], false);
// am/pm
for (int fieldIdx = AM; fieldIdx <= PM; fieldIdx++) {
int lastIndex = args[0].equals("CLDR") ? 11 : PM;
for (int fieldIdx = AM; fieldIdx <= lastIndex; fieldIdx++) {
checkValueRange(calTypes[calIdx], AM_PM, fieldIdx, LONG, testLocs[locIdx], true);
}
checkValueRange(calTypes[calIdx], AM_PM, AM-1, LONG, testLocs[locIdx], false);
checkValueRange(calTypes[calIdx], AM_PM, PM+1, LONG, testLocs[locIdx], false);
checkValueRange(calTypes[calIdx], AM_PM, lastIndex+1, LONG, testLocs[locIdx], false);
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,12 +23,13 @@
/*
* @test
* @bug 8000983 8008577
* @bug 8000983 8008577 8247781
* @summary Unit test for narrow names support. This test is locale data-dependent
* and assumes that both JRE and CLDR have the same narrow names.
* and assumes that both COMPAT and CLDR have the same narrow names if not
* explicitly specified.
* @modules jdk.localedata
* @comment Locale providers: JRE,SPI
* @run main/othervm -Djava.locale.providers=JRE,SPI NarrowNamesTest JRE,SPI
* @comment Locale providers: COMPAT,SPI
* @run main/othervm -Djava.locale.providers=COMPAT,SPI NarrowNamesTest COMPAT,SPI
* @comment Locale providers: CLDR
* @run main/othervm -Djava.locale.providers=CLDR NarrowNamesTest CLDR
*/
@ -50,11 +51,9 @@ public class NarrowNamesTest {
private static int errors = 0;
private static String providers;
// This test is locale data-dependent.
public static void main(String[] args) {
providers = args[0];
String providers = args[0];
test(US, ERA, "B",
ERA, BC, YEAR, 1);
@ -95,10 +94,28 @@ public class NarrowNamesTest {
"Sat" // abb Saturday
);
testMap(US, DAY_OF_WEEK, NARROW_FORMAT); // expect null
testMap(US, AM_PM, ALL_STYLES,
"AM", "PM",
RESET_INDEX,
"a", "p");
if (providers.startsWith("CLDR")) {
testMap(US, AM_PM, ALL_STYLES,
"AM",
"PM",
"midnight",
"noon",
"in the morning",
"",
"in the afternoon",
"",
"in the evening",
"",
"at night",
"",
RESET_INDEX,
"a", "p", "mi", "n", "", "", "", "", "", "", "", "");
} else {
testMap(US, AM_PM, ALL_STYLES,
"AM", "PM",
RESET_INDEX,
"a", "p");
}
testMap(JAJPJP, DAY_OF_WEEK, NARROW_STANDALONE,
"", // 1-based indexing for DAY_OF_WEEK
"\u65e5",
@ -176,16 +193,16 @@ public class NarrowNamesTest {
if (expected.length > 0) {
expectedMap = new TreeMap<>(LengthBasedComparator.INSTANCE);
int index = 0;
for (int i = 0; i < expected.length; i++) {
if (expected[i].isEmpty()) {
for (String s : expected) {
if (s.isEmpty()) {
index++;
continue;
}
if (expected[i] == RESET_INDEX) {
if (s == RESET_INDEX) {
index = 0;
continue;
}
expectedMap.put(expected[i], index++);
expectedMap.put(s, index++);
}
}
Calendar cal = Calendar.getInstance(locale);