8318761: MessageFormat pattern support for CompactNumberFormat, ListFormat, and DateTimeFormatter
Reviewed-by: naoto, rriggs
This commit is contained in:
parent
d695af89f6
commit
00ffc42cef
src/java.base/share/classes/java/text
test/jdk/java/text/Format/MessageFormat
@ -482,6 +482,31 @@ public abstract class DateFormat extends Format {
|
||||
*/
|
||||
public static final int DEFAULT = MEDIUM;
|
||||
|
||||
/**
|
||||
* A DateFormat style.
|
||||
* {@code Style} is an enum which corresponds to the DateFormat style
|
||||
* constants. Use {@code getValue()} to retrieve the associated int style
|
||||
* value.
|
||||
*/
|
||||
enum Style {
|
||||
|
||||
FULL(DateFormat.FULL),
|
||||
LONG(DateFormat.LONG),
|
||||
MEDIUM(DateFormat.MEDIUM),
|
||||
SHORT(DateFormat.SHORT),
|
||||
DEFAULT(DateFormat.MEDIUM);
|
||||
|
||||
private final int value;
|
||||
|
||||
Style(int value){
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time formatter with the default formatting style
|
||||
* for the default {@link java.util.Locale.Category#FORMAT FORMAT} locale.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2024, 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
|
||||
@ -677,6 +677,33 @@ public abstract class NumberFormat extends Format {
|
||||
return getInstance(locale, formatStyle, COMPACTSTYLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method compares the passed NumberFormat to a number of pre-defined
|
||||
* style NumberFormat instances, (created with the passed locale). Returns a
|
||||
* matching FormatStyle string if found, otherwise null.
|
||||
* This method is used by MessageFormat to provide string pattens for NumberFormat
|
||||
* Subformats. Any future pre-defined NumberFormat styles should be added to this method.
|
||||
*/
|
||||
static String matchToStyle(NumberFormat fmt, Locale locale) {
|
||||
if (fmt.equals(NumberFormat.getInstance(locale))) {
|
||||
return "";
|
||||
} else if (fmt.equals(NumberFormat.getCurrencyInstance(locale))) {
|
||||
return "currency";
|
||||
} else if (fmt.equals(NumberFormat.getPercentInstance(locale))) {
|
||||
return "percent";
|
||||
} else if (fmt.equals(NumberFormat.getIntegerInstance(locale))) {
|
||||
return "integer";
|
||||
} else if (fmt.equals(NumberFormat.getCompactNumberInstance(locale,
|
||||
NumberFormat.Style.SHORT))) {
|
||||
return "compact_short";
|
||||
} else if (fmt.equals(NumberFormat.getCompactNumberInstance(locale,
|
||||
NumberFormat.Style.LONG))) {
|
||||
return "compact_long";
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all locales for which the
|
||||
* {@code get*Instance} methods of this class can return
|
||||
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8318761
|
||||
* @summary Test MessageFormatPattern ability to recognize and produce
|
||||
* appropriate FormatType and FormatStyle for CompactNumberFormat.
|
||||
* @run junit CompactSubFormats
|
||||
*/
|
||||
|
||||
import java.text.CompactNumberFormat;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.text.MessageFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class CompactSubFormats {
|
||||
|
||||
// Ensure the built-in FormatType and FormatStyles for cnFmt are as expected
|
||||
@Test
|
||||
public void applyPatternTest() {
|
||||
var mFmt = new MessageFormat(
|
||||
"{0,number,compact_short}{1,number,compact_long}");
|
||||
var compactShort = NumberFormat.getCompactNumberInstance(
|
||||
mFmt.getLocale(), NumberFormat.Style.SHORT);
|
||||
var compactLong = NumberFormat.getCompactNumberInstance(
|
||||
mFmt.getLocale(), NumberFormat.Style.LONG);
|
||||
assertEquals(mFmt.getFormatsByArgumentIndex()[0], compactShort);
|
||||
assertEquals(mFmt.getFormatsByArgumentIndex()[1], compactLong);
|
||||
}
|
||||
|
||||
// Ensure that only 'compact_short' and 'compact_long' are recognized as
|
||||
// compact number modifiers. All other compact_XX should be interpreted as
|
||||
// a subformatPattern for a DecimalFormat
|
||||
@Test
|
||||
public void recognizedCompactStylesTest() {
|
||||
// An exception won't be thrown since 'compact_regular' will be interpreted as a
|
||||
// subformatPattern.
|
||||
assertEquals(new DecimalFormat("compact_regular"),
|
||||
new MessageFormat("{0,number,compact_regular}").getFormatsByArgumentIndex()[0]);
|
||||
}
|
||||
|
||||
// SHORT and LONG CompactNumberFormats should produce correct patterns
|
||||
@Test
|
||||
public void toPatternTest() {
|
||||
var mFmt = new MessageFormat("{0}{1}");
|
||||
mFmt.setFormatByArgumentIndex(0, NumberFormat.getCompactNumberInstance(
|
||||
mFmt.getLocale(), NumberFormat.Style.SHORT));
|
||||
mFmt.setFormatByArgumentIndex(1, NumberFormat.getCompactNumberInstance(
|
||||
mFmt.getLocale(), NumberFormat.Style.LONG));
|
||||
assertEquals("{0,number,compact_short}{1,number,compact_long}", mFmt.toPattern());
|
||||
}
|
||||
|
||||
// A custom cnFmt cannot be recognized, thus does not produce any built-in pattern
|
||||
@Test
|
||||
public void badToPatternTest() {
|
||||
var mFmt = new MessageFormat("{0}");
|
||||
// Non-recognizable compactNumberFormat
|
||||
mFmt.setFormatByArgumentIndex(0, new CompactNumberFormat("",
|
||||
DecimalFormatSymbols.getInstance(Locale.US), new String[]{""}));
|
||||
// Default behavior of unrecognizable Formats is a FormatElement
|
||||
// in the form of { ArgumentIndex }
|
||||
assertEquals("{0}", mFmt.toPattern());
|
||||
}
|
||||
}
|
98
test/jdk/java/text/Format/MessageFormat/ListSubFormats.java
Normal file
98
test/jdk/java/text/Format/MessageFormat/ListSubFormats.java
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8318761
|
||||
* @summary Test MessageFormatPattern ability to recognize and produce the
|
||||
* appropriate FormatType and FormatStyle for ListFormat. ListFormat's
|
||||
* STANDARD, OR, and UNIT types are supported as built-in patterns for
|
||||
* MessageFormat. All types use the FULL style.
|
||||
* @run junit ListSubFormats
|
||||
*/
|
||||
|
||||
import java.text.ListFormat;
|
||||
import java.text.MessageFormat;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class ListSubFormats {
|
||||
|
||||
// Recognize the 'list' FormatType as well as '', 'or', and
|
||||
// 'unit' associated FormatStyles
|
||||
@Test
|
||||
public void applyPatternTest() {
|
||||
var mFmt = new MessageFormat("{0,list}{1,list,or}{2,list,unit}");
|
||||
var listStandard = ListFormat.getInstance(mFmt.getLocale(),
|
||||
ListFormat.Type.STANDARD, ListFormat.Style.FULL);
|
||||
var listOr = ListFormat.getInstance(mFmt.getLocale(),
|
||||
ListFormat.Type.OR, ListFormat.Style.FULL);
|
||||
var listUnit = ListFormat.getInstance(mFmt.getLocale(),
|
||||
ListFormat.Type.UNIT, ListFormat.Style.FULL);
|
||||
assertEquals(mFmt.getFormatsByArgumentIndex()[0], listStandard);
|
||||
assertEquals(mFmt.getFormatsByArgumentIndex()[1], listOr);
|
||||
assertEquals(mFmt.getFormatsByArgumentIndex()[2], listUnit);
|
||||
}
|
||||
|
||||
// Ensure incorrect FormatElement pattern throws IAE
|
||||
// java.text.ListFormat does not support String subformatPatterns
|
||||
@Test
|
||||
public void badApplyPatternTest() {
|
||||
// Wrong FormatStyle
|
||||
IllegalArgumentException exc = assertThrows(IllegalArgumentException.class, () ->
|
||||
new MessageFormat("{0,list,standard}"));
|
||||
assertEquals("Unexpected modifier for List: standard", exc.getMessage());
|
||||
|
||||
// Wrong FormatType
|
||||
exc = assertThrows(IllegalArgumentException.class, () ->
|
||||
new MessageFormat("{0,listt,or}"));
|
||||
assertEquals("unknown format type: listt", exc.getMessage());
|
||||
|
||||
}
|
||||
|
||||
// STANDARD, OR, UNIT ListFormats (with FULL style) should
|
||||
// produce correct patterns.
|
||||
@Test
|
||||
public void toPatternTest() {
|
||||
var mFmt = new MessageFormat("{0}{1}{2}");
|
||||
mFmt.setFormatByArgumentIndex(0,
|
||||
ListFormat.getInstance(mFmt.getLocale(), ListFormat.Type.STANDARD, ListFormat.Style.FULL));
|
||||
mFmt.setFormatByArgumentIndex(1,
|
||||
ListFormat.getInstance(mFmt.getLocale(), ListFormat.Type.OR, ListFormat.Style.FULL));
|
||||
mFmt.setFormatByArgumentIndex(2,
|
||||
ListFormat.getInstance(mFmt.getLocale(), ListFormat.Type.UNIT, ListFormat.Style.FULL));
|
||||
assertEquals("{0,list}{1,list,or}{2,list,unit}", mFmt.toPattern());
|
||||
}
|
||||
|
||||
// A custom ListFormat cannot be recognized, thus does not produce any built-in pattern
|
||||
@Test
|
||||
public void badToPatternTest() {
|
||||
var mFmt = new MessageFormat("{0}");
|
||||
mFmt.setFormatByArgumentIndex(0,
|
||||
ListFormat.getInstance(mFmt.getLocale(), ListFormat.Type.UNIT, ListFormat.Style.NARROW));
|
||||
assertEquals("{0}", mFmt.toPattern());
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@
|
||||
/*
|
||||
* @test
|
||||
* @summary Validate some exceptions in MessageFormat
|
||||
* @bug 6481179 8039165
|
||||
* @bug 6481179 8039165 8318761
|
||||
* @run junit MessageFormatExceptions
|
||||
*/
|
||||
|
||||
@ -39,6 +39,15 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class MessageFormatExceptions {
|
||||
|
||||
// Any exception for a Subformat should be re-thrown as propagated as an IAE
|
||||
// to the MessageFormat
|
||||
@Test
|
||||
public void rethrowAsIAE() {
|
||||
// Same Subformat pattern for ChoiceFormat throws NumberFormatException
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> new MessageFormat("{0,choice,0foo#foo}"));
|
||||
}
|
||||
|
||||
// MessageFormat should throw NPE when constructed with a null pattern
|
||||
@Test
|
||||
public void nullPatternTest() {
|
||||
@ -57,6 +66,9 @@ public class MessageFormatExceptions {
|
||||
// Fails when constructor invokes applyPattern()
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> new MessageFormat("{0, date}", null));
|
||||
// Same as above, but with Subformat pattern
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> new MessageFormat("{0, date,dd}", null));
|
||||
// Fail when constructor invokes applyPattern()
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> new MessageFormat("{0, number}", null));
|
||||
|
204
test/jdk/java/text/Format/MessageFormat/TemporalSubFormats.java
Normal file
204
test/jdk/java/text/Format/MessageFormat/TemporalSubFormats.java
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8318761
|
||||
* @summary Test MessageFormatPattern ability to recognize the appropriate
|
||||
* FormatType and FormatStyle for DateTimeFormatter(ClassicFormat).
|
||||
* This includes the types dtf_time, dtf_date, dtf_datetime,
|
||||
* and the DateTimeFormatter predefined formatters.
|
||||
* @run junit TemporalSubFormats
|
||||
*/
|
||||
|
||||
import java.text.Format;
|
||||
import java.text.MessageFormat;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.FormatStyle;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class TemporalSubFormats {
|
||||
|
||||
// Check that applying the built-in DateTimeFormatter types returns the
|
||||
// correct Format and formats properly. Patterns are case-insensitive
|
||||
@ParameterizedTest
|
||||
@MethodSource("preDefinedTypes")
|
||||
public void preDefinedPatternsTest(String pattern, Format fmt) {
|
||||
var mFmt = new MessageFormat("quux{0,"+pattern+"}quux");
|
||||
Object[] temporals = new Object[]{LocalDate.now(), LocalTime.now(),
|
||||
ZonedDateTime.now(), LocalDateTime.now(), OffsetDateTime.now(), Instant.now()};
|
||||
for (Object val : temporals) {
|
||||
// Wrap in Object array for MessageFormat
|
||||
Object[] wrappedVal = new Object[]{val};
|
||||
|
||||
try {
|
||||
String mFmtted = mFmt.format(wrappedVal);
|
||||
// If current format can support the time object. Check equality of result
|
||||
assertEquals(mFmtted, "quux"+fmt.format(val)+"quux");
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
// Otherwise, ensure both throw IAE on unsupported field
|
||||
assertThrows(IllegalArgumentException.class, () -> fmt.format(val));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Provides String patterns and the associated (standalone) FormatType
|
||||
// Values should be case-insensitive
|
||||
private static Stream<Arguments> preDefinedTypes() {
|
||||
return Stream.of(
|
||||
Arguments.of("BASIC_ISO_DATE", DateTimeFormatter.BASIC_ISO_DATE.toFormat()),
|
||||
Arguments.of("ISO_LOCAL_DATE", DateTimeFormatter.ISO_LOCAL_DATE.toFormat()),
|
||||
Arguments.of("ISO_OFFSET_DATE", DateTimeFormatter.ISO_OFFSET_DATE.toFormat()),
|
||||
Arguments.of("ISO_DATE", DateTimeFormatter.ISO_DATE.toFormat()),
|
||||
Arguments.of("iso_local_time", DateTimeFormatter.ISO_LOCAL_TIME.toFormat()),
|
||||
Arguments.of("ISO_OFFSET_TIME", DateTimeFormatter.ISO_OFFSET_TIME.toFormat()),
|
||||
Arguments.of("iso_time", DateTimeFormatter.ISO_TIME.toFormat()),
|
||||
Arguments.of("ISO_LOCAL_DATE_TIME", DateTimeFormatter.ISO_LOCAL_DATE_TIME.toFormat()),
|
||||
Arguments.of("ISO_OFFSET_DATE_TIME", DateTimeFormatter.ISO_OFFSET_DATE_TIME.toFormat()),
|
||||
Arguments.of("ISO_ZONED_DATE_TIME", DateTimeFormatter.ISO_ZONED_DATE_TIME.toFormat()),
|
||||
Arguments.of("ISO_DATE_TIME", DateTimeFormatter.ISO_DATE_TIME.toFormat()),
|
||||
Arguments.of("ISO_ORDINAL_DATE", DateTimeFormatter.ISO_ORDINAL_DATE.toFormat()),
|
||||
Arguments.of("iso_week_date", DateTimeFormatter.ISO_WEEK_DATE.toFormat()),
|
||||
Arguments.of("ISO_INSTANT", DateTimeFormatter.ISO_INSTANT.toFormat()),
|
||||
Arguments.of("RFC_1123_DATE_TIME", DateTimeFormatter.RFC_1123_DATE_TIME.toFormat())
|
||||
);
|
||||
}
|
||||
|
||||
// Check that the appropriate FormatType/Style combo returns correct Format
|
||||
// Unlike the other pattern tests, the formatted output is used to check
|
||||
// equality, as DateTimeFormatter does not implement equals()
|
||||
@ParameterizedTest
|
||||
@MethodSource("styles")
|
||||
public void applyPatternTest(String style, FormatStyle fStyle) {
|
||||
var time = ZonedDateTime.now();
|
||||
var date = LocalDate.now();
|
||||
|
||||
// Test dtf_date
|
||||
var dFmt = new MessageFormat("{0,dtf_date"+style+"}");
|
||||
assertEquals(DateTimeFormatter.ofLocalizedDate(fStyle).withLocale(
|
||||
dFmt.getLocale()).toFormat().format(date),
|
||||
dFmt.getFormatsByArgumentIndex()[0].format(date));
|
||||
|
||||
// Test dtf_time
|
||||
var tFmt = new MessageFormat("{0,dtf_time"+style+"}");
|
||||
assertEquals(DateTimeFormatter.ofLocalizedTime(fStyle).withLocale(
|
||||
tFmt.getLocale()).toFormat().format(time),
|
||||
tFmt.getFormatsByArgumentIndex()[0].format(time));
|
||||
|
||||
// Test dtf_datetime
|
||||
var dtFmt = new MessageFormat("{0,dtf_datetime"+style+"}");
|
||||
assertEquals(DateTimeFormatter.ofLocalizedDateTime(fStyle).withLocale(
|
||||
dtFmt.getLocale()).toFormat().format(time),
|
||||
dtFmt.getFormatsByArgumentIndex()[0].format(time));
|
||||
}
|
||||
|
||||
// Provides String patterns and the associated FormatStyle
|
||||
private static Stream<Arguments> styles() {
|
||||
return Stream.of(
|
||||
Arguments.of("", FormatStyle.MEDIUM),
|
||||
Arguments.of(",short", FormatStyle.SHORT),
|
||||
Arguments.of(",medium", FormatStyle.MEDIUM),
|
||||
Arguments.of(",long", FormatStyle.LONG),
|
||||
Arguments.of(",full", FormatStyle.FULL)
|
||||
);
|
||||
}
|
||||
|
||||
// Test that a proper Format from a SubformatPattern can be reproduced
|
||||
@Test
|
||||
public void subformatPatternTest() {
|
||||
// SubformatPattern invokes the same method for both dtf_date,
|
||||
// dtf_time, and dtf_datetime
|
||||
var pattern = "d MMM uuuu";
|
||||
var date = LocalDate.now();
|
||||
|
||||
// Test dtf_date
|
||||
var dFmt = new MessageFormat("{0,dtf_date,"+pattern+"}");
|
||||
assertEquals(DateTimeFormatter.ofPattern(pattern,dFmt.getLocale()).toFormat().format(date),
|
||||
dFmt.getFormatsByArgumentIndex()[0].format(date));
|
||||
|
||||
// Test dtf_time
|
||||
var tFmt = new MessageFormat("{0,dtf_time,"+pattern+"}");
|
||||
assertEquals(DateTimeFormatter.ofPattern(pattern,tFmt.getLocale()).toFormat().format(date),
|
||||
tFmt.getFormatsByArgumentIndex()[0].format(date));
|
||||
|
||||
// Test dtf_datetime
|
||||
var dtFmt = new MessageFormat("{0,dtf_datetime,"+pattern+"}");
|
||||
assertEquals(DateTimeFormatter.ofPattern(pattern,dtFmt.getLocale()).toFormat().format(date),
|
||||
dtFmt.getFormatsByArgumentIndex()[0].format(date));
|
||||
}
|
||||
|
||||
// Ensure that only the supported built-in FormatStyles or a
|
||||
// valid SubformatPattern are recognized
|
||||
@Test
|
||||
public void badApplyPatternTest() {
|
||||
// Not a supported FormatStyle: throws the underlying IAE from DTF
|
||||
// as it is interpreted as a subformatPattern
|
||||
IllegalArgumentException exc = assertThrows(IllegalArgumentException.class, () ->
|
||||
new MessageFormat("{0,dtf_date,longer}"));
|
||||
assertEquals("Unknown pattern letter: l", exc.getMessage());
|
||||
|
||||
// Not a legal SubformatPattern: throws the underlying IAE from DTF
|
||||
exc = assertThrows(IllegalArgumentException.class, () ->
|
||||
new MessageFormat("{0,dtf_date,VVV}"));
|
||||
assertEquals("Pattern letter count must be 2: V", exc.getMessage());
|
||||
|
||||
// Pre-defined ISO style does not exist and should be ignored
|
||||
assertDoesNotThrow(() -> new MessageFormat("{0,BASIC_ISO_DATE,foo}"),
|
||||
"Style on a pre-defined DTF should be ignored, instead of throwing an exception");
|
||||
}
|
||||
|
||||
// DateTimeFormatters cannot be recognized when toPattern() is invoked
|
||||
// Default behavior of unrecognizable Formats is a FormatElement
|
||||
// in the form of { ArgumentIndex }
|
||||
@Test
|
||||
public void nonRecognizableToPatternTest() {
|
||||
// Check SubformatPattern
|
||||
var validPattern = "yy";
|
||||
var mFmt = new MessageFormat("{0}");
|
||||
mFmt.setFormatByArgumentIndex(0, DateTimeFormatter.ofPattern(validPattern).toFormat());
|
||||
assertEquals("{0}", mFmt.toPattern());
|
||||
|
||||
// Check pre-defined styles
|
||||
var dFmt = new MessageFormat("{0,dtf_date,long}");
|
||||
assertEquals("{0}", dFmt.toPattern());
|
||||
var tFmt = new MessageFormat("{0,dtf_time,long}");
|
||||
assertEquals("{0}", tFmt.toPattern());
|
||||
var dtFmt = new MessageFormat("{0,dtf_datetime,long}");
|
||||
assertEquals("{0}", dtFmt.toPattern());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user