/* * Copyright (c) 2017, 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 8176841 * @summary Tests java.time classes deals with Unicode extensions * correctly. * @modules jdk.localedata * @run testng/othervm -Djava.locale.providers=CLDR JavaTimeTests */ import static org.testng.Assert.assertEquals; import java.time.DayOfWeek; import java.time.ZonedDateTime; import java.time.ZoneId; import java.time.chrono.Chronology; import java.time.chrono.HijrahChronology; import java.time.chrono.JapaneseChronology; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.FormatStyle; import java.time.temporal.WeekFields; import java.util.Locale; import java.util.TimeZone; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** * Test JavaTime with BCP47 U extensions */ @Test public class JavaTimeTests { private static TimeZone defaultTZ; private static final Chronology JAPANESE = JapaneseChronology.INSTANCE; private static final Chronology HIJRAH = HijrahChronology.INSTANCE; private static final ZoneId ASIATOKYO = ZoneId.of("Asia/Tokyo"); private static final ZoneId AMLA = ZoneId.of("America/Los_Angeles"); private static final Locale JPTYO = Locale.forLanguageTag("en-u-tz-jptyo"); private static final Locale JCAL = Locale.forLanguageTag("en-u-ca-japanese"); private static final Locale HCAL = Locale.forLanguageTag("en-u-ca-islamic-umalqura"); private static final Locale FW_SUN = Locale.forLanguageTag("en-US-u-fw-sun"); private static final Locale FW_MON = Locale.forLanguageTag("en-US-u-fw-mon"); private static final Locale FW_TUE = Locale.forLanguageTag("en-US-u-fw-tue"); private static final Locale FW_WED = Locale.forLanguageTag("en-US-u-fw-wed"); private static final Locale FW_THU = Locale.forLanguageTag("en-US-u-fw-thu"); private static final Locale FW_FRI = Locale.forLanguageTag("en-US-u-fw-fri"); private static final Locale FW_SAT = Locale.forLanguageTag("en-US-u-fw-sat"); private static final Locale RG_GB = Locale.forLanguageTag("en-US-u-rg-gbzzzz"); private static final ZonedDateTime ZDT = ZonedDateTime.of(2017, 8, 10, 15, 15, 0, 0, AMLA); private static final String PATTERN = "GGGG MMMM-dd-uu HH:mm:ss zzzz"; @BeforeTest public void beforeTest() { defaultTZ = TimeZone.getDefault(); TimeZone.setDefault(TimeZone.getTimeZone(AMLA)); } @AfterTest public void afterTest() { TimeZone.setDefault(defaultTZ); } @DataProvider(name="withLocale") Object[][] withLocale() { return new Object[][] { // Locale, Chrono override, Zone override, Expected Chrono, Expected Zone, // Expected formatted string {Locale.JAPAN, null, null, null, null, "2017\u5e748\u670810\u65e5\u6728\u66dc\u65e5 15\u664215\u520600\u79d2 \u30a2\u30e1\u30ea\u30ab\u592a\u5e73\u6d0b\u590f\u6642\u9593" }, {Locale.JAPAN, JAPANESE, null, JAPANESE, null, "\u5e73\u621029\u5e748\u670810\u65e5\u6728\u66dc\u65e5 15\u664215\u520600\u79d2 \u30a2\u30e1\u30ea\u30ab\u592a\u5e73\u6d0b\u590f\u6642\u9593" }, {Locale.JAPAN, JAPANESE, ASIATOKYO, JAPANESE, ASIATOKYO, "\u5e73\u621029\u5e748\u670811\u65e5\u91d1\u66dc\u65e5 7\u664215\u520600\u79d2 \u65e5\u672c\u6a19\u6e96\u6642" }, {JCAL, null, null, JAPANESE, null, "Thursday, August 10, 29 Heisei at 3:15:00 PM Pacific Daylight Time" }, {JCAL, HIJRAH, null, JAPANESE, null, "Thursday, August 10, 29 Heisei at 3:15:00 PM Pacific Daylight Time" }, {HCAL, JAPANESE, null, HIJRAH, null, "Thursday, Dhu\u02bbl-Qi\u02bbdah 18, 1438 AH at 3:15:00 PM Pacific Daylight Time" }, {JPTYO, null, null, null, ASIATOKYO, "Friday, August 11, 2017 at 7:15:00 AM Japan Standard Time" }, {JPTYO, null, AMLA, null, ASIATOKYO, "Friday, August 11, 2017 at 7:15:00 AM Japan Standard Time" }, // invalid tz {Locale.forLanguageTag("en-US-u-tz-jpzzz"), null, null, null, null, "Thursday, August 10, 2017 at 3:15:00 PM Pacific Daylight Time" }, {Locale.forLanguageTag("en-US-u-tz-jpzzz"), null, AMLA, null, AMLA, "Thursday, August 10, 2017 at 3:15:00 PM Pacific Daylight Time" }, {RG_GB, null, null, null, null, "Thursday, 10 August 2017 at 15:15:00 Pacific Daylight Time" }, }; } @DataProvider(name="firstDayOfWeek") Object[][] firstDayOfWeek () { return new Object[][] { // Locale, Expected DayOfWeek, {Locale.US, DayOfWeek.SUNDAY}, {FW_SUN, DayOfWeek.SUNDAY}, {FW_MON, DayOfWeek.MONDAY}, {FW_TUE, DayOfWeek.TUESDAY}, {FW_WED, DayOfWeek.WEDNESDAY}, {FW_THU, DayOfWeek.THURSDAY}, {FW_FRI, DayOfWeek.FRIDAY}, {FW_SAT, DayOfWeek.SATURDAY}, // invalid case {Locale.forLanguageTag("en-US-u-fw-xxx"), DayOfWeek.SUNDAY}, // region override {RG_GB, DayOfWeek.MONDAY}, {Locale.forLanguageTag("zh-CN-u-rg-eszzzz"), DayOfWeek.MONDAY}, // "fw" and "rg". {Locale.forLanguageTag("en-US-u-fw-wed-rg-gbzzzz"), DayOfWeek.WEDNESDAY}, {Locale.forLanguageTag("en-US-u-fw-xxx-rg-gbzzzz"), DayOfWeek.MONDAY}, {Locale.forLanguageTag("en-US-u-fw-xxx-rg-zzzz"), DayOfWeek.SUNDAY}, }; } @DataProvider(name="minDaysInFirstWeek") Object[][] minDaysInFrstWeek () { return new Object[][] { // Locale, Expected minDay, {Locale.US, 1}, // region override {RG_GB, 4}, {Locale.forLanguageTag("zh-CN-u-rg-eszzzz"), 4}, }; } @DataProvider(name="ofPattern") Object[][] ofPattern() { return new Object[][] { // Locale, Expected Chrono, Expected Zone, // Expected formatted string {JCAL, JAPANESE, null, "Heisei August-10-17 15:15:00 Pacific Daylight Time" }, {HCAL, HIJRAH, null, "AH Dhu\u02bbl-Qi\u02bbdah-18-38 15:15:00 Pacific Daylight Time" }, {JPTYO, null, ASIATOKYO, "Anno Domini August-11-17 07:15:00 Japan Standard Time" }, {Locale.forLanguageTag("en-US-u-tz-jpzzz"), null, null, "Anno Domini August-10-17 15:15:00 Pacific Daylight Time" }, {RG_GB, null, null, "Anno Domini August-10-17 15:15:00 Pacific Daylight Time" }, }; } @Test(dataProvider="withLocale") public void test_withLocale(Locale locale, Chronology chrono, ZoneId zone, Chronology chronoExpected, ZoneId zoneExpected, String formatExpected) { DateTimeFormatter dtf = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.FULL) .withChronology(chrono).withZone(zone).withLocale(locale); assertEquals(dtf.getChronology(), chronoExpected); assertEquals(dtf.getZone(), zoneExpected); String formatted = dtf.format(ZDT); assertEquals(formatted, formatExpected); assertEquals(dtf.parse(formatted, ZonedDateTime::from), zoneExpected != null ? ZDT.withZoneSameInstant(zoneExpected) : ZDT); } @Test(dataProvider="firstDayOfWeek") public void test_firstDayOfWeek(Locale locale, DayOfWeek dowExpected) { DayOfWeek dow = WeekFields.of(locale).getFirstDayOfWeek(); assertEquals(dow, dowExpected); } @Test(dataProvider="minDaysInFirstWeek") public void test_minDaysInFirstWeek(Locale locale, int minDaysExpected) { int minDays = WeekFields.of(locale).getMinimalDaysInFirstWeek(); assertEquals(minDays, minDaysExpected); } @Test(dataProvider="ofPattern") public void test_ofPattern(Locale locale, Chronology chronoExpected, ZoneId zoneExpected, String formatExpected) { DateTimeFormatter dtf = DateTimeFormatter.ofPattern(PATTERN, locale); assertEquals(dtf.getChronology(), chronoExpected); assertEquals(dtf.getZone(), zoneExpected); String formatted = dtf.format(ZDT); assertEquals(formatted, formatExpected); assertEquals(dtf.parse(formatted, ZonedDateTime::from), zoneExpected != null ? ZDT.withZoneSameInstant(zoneExpected) : ZDT); } @Test(dataProvider="ofPattern") public void test_toFormatter(Locale locale, Chronology chronoExpected, ZoneId zoneExpected, String formatExpected) { DateTimeFormatter dtf = new DateTimeFormatterBuilder().appendPattern(PATTERN).toFormatter(locale); assertEquals(dtf.getChronology(), chronoExpected); assertEquals(dtf.getZone(), zoneExpected); String formatted = dtf.format(ZDT); assertEquals(formatted, formatExpected); assertEquals(dtf.parse(formatted, ZonedDateTime::from), zoneExpected != null ? ZDT.withZoneSameInstant(zoneExpected) : ZDT); } }