1 /*
   2  * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 8154520
  27  * @summary This test verifies that the localized text for "GMT" from CLDR is 
  28  * applied/recognized during printing/parsing timestamps. For example, the 
  29  * localized text for "GMT" on some particular locale may be "UTC", and the 
  30  * resulting formatted string should have UTC+<offset> (instead of GMT+<offset>). 
  31  * Since the test relies on CLDR data, the "expected" text in the test data may 
  32  * require to be modified in accordance with changes to CLDR, if any. 
  33  * @modules jdk.localedata
  34  */
  35 
  36 package test.java.time.format;
  37 
  38 import static org.testng.Assert.assertEquals;
  39 
  40 import java.time.LocalDateTime;
  41 import java.time.OffsetDateTime;
  42 import java.time.ZoneOffset;
  43 import java.time.ZonedDateTime;
  44 import java.time.format.DateTimeFormatter;
  45 import java.time.format.DateTimeFormatterBuilder;
  46 import java.time.format.TextStyle;
  47 import java.util.Locale;
  48 import java.util.Objects;
  49 
  50 import org.testng.annotations.DataProvider;
  51 import org.testng.annotations.Test;
  52 
  53 /**
  54  * Test DateTimeFormatterBuilder.appendOffset().
  55  */
  56 @Test
  57 public class TestLocalizedOffsetPrinterParser {
  58 
  59     private static final LocalDateTime DT_2012_06_30_12_30_40 = LocalDateTime.of(2012, 6, 30, 12, 30, 40);
  60     
  61     private static final ZoneOffset OFFSET_UTC = ZoneOffset.UTC;
  62     private static final ZoneOffset OFFSET_P012345 = ZoneOffset.ofHoursMinutesSeconds(1, 23, 45);
  63     private static final ZoneOffset OFFSET_P000045 = ZoneOffset.ofHoursMinutesSeconds(0, 0, 45);
  64     private static final ZoneOffset OFFSET_M0100 = ZoneOffset.ofHours(-1);
  65     private static final ZoneOffset OFFSET_M0123 = ZoneOffset.ofHoursMinutes(-1, -23);
  66     private static final ZoneOffset OFFSET_M012345 = ZoneOffset.ofHoursMinutesSeconds(-1, -23, -45);
  67     private static final ZoneOffset OFFSET_M000045 = ZoneOffset.ofHoursMinutesSeconds(0, 0, -45);
  68 
  69     @DataProvider(name="print_localized_custom_locale")
  70     Object[][] data_print_localized_custom_locale() {
  71         return new Object[][] {
  72                 {TextStyle.SHORT, DT_2012_06_30_12_30_40, OFFSET_M0123, new Locale("am"), "\u1302 \u12a4\u121d \u1272-1:23"},
  73                 {TextStyle.FULL, DT_2012_06_30_12_30_40, OFFSET_M0100, new Locale("ar"), "\u063a\u0631\u064a\u0646\u062a\u0634-01:00"},
  74                 {TextStyle.FULL, DT_2012_06_30_12_30_40, OFFSET_P012345, new Locale("bg"), "\u0413\u0440\u0438\u043d\u0443\u0438\u0447+01:23:45"},
  75                 {TextStyle.FULL, DT_2012_06_30_12_30_40, OFFSET_M000045, Locale.CHINESE, "GMT-00:00:45"},
  76                 {TextStyle.FULL, DT_2012_06_30_12_30_40, OFFSET_P012345, Locale.ENGLISH, "GMT+01:23:45"},
  77                 {TextStyle.SHORT, DT_2012_06_30_12_30_40, OFFSET_M012345, new Locale("eo"), "GMT-1:23:45"},
  78                 {TextStyle.FULL, DT_2012_06_30_12_30_40, OFFSET_P000045, Locale.FRANCE, "UTC+00:00:45"},
  79                 {TextStyle.SHORT, DT_2012_06_30_12_30_40, OFFSET_M0100, new Locale("ga"), "MAG-1"},
  80                 {TextStyle.SHORT, DT_2012_06_30_12_30_40, OFFSET_UTC, new Locale("km"), "\u1798\u17c9\u17c4\u1784\u200b\u179f\u1780\u179b"},
  81                 {TextStyle.FULL, DT_2012_06_30_12_30_40, OFFSET_UTC, new Locale("ml"), "\u0d1c\u0d3f\u0d0e\u0d02\u0d1f\u0d3f"},
  82                 {TextStyle.FULL, DT_2012_06_30_12_30_40, OFFSET_P012345, new Locale("mr"), "[GMT]+01:23:45"},
  83                 {TextStyle.SHORT, DT_2012_06_30_12_30_40, OFFSET_P012345, new Locale("se"), "UTC+1:23:45"},
  84                 {TextStyle.FULL, DT_2012_06_30_12_30_40, OFFSET_M0100, new Locale("yo", "BJ"), "WAT-01:00"}
  85         };
  86     }
  87 
  88     @Test(dataProvider="print_localized_custom_locale")
  89     public void test_print_localized_custom_locale(TextStyle style, LocalDateTime ldt, ZoneOffset offset, Locale locale, String expected) {
  90         
  91         Objects.requireNonNull(locale, "Locale must not be null");
  92         
  93         OffsetDateTime odt = OffsetDateTime.of(ldt, offset);
  94         ZonedDateTime zdt = ldt.atZone(offset);
  95         
  96         DateTimeFormatter f = new DateTimeFormatterBuilder().appendLocalizedOffset(style).toFormatter(locale);
  97         assertEquals(f.format(odt), expected);
  98         assertEquals(f.format(zdt), expected);
  99         assertEquals(f.parse(expected, ZoneOffset::from), offset);
 100 
 101         if (style == TextStyle.FULL) {
 102             f = new DateTimeFormatterBuilder().appendPattern("ZZZZ").toFormatter(locale);
 103             assertEquals(f.format(odt), expected);
 104             assertEquals(f.format(zdt), expected);
 105             assertEquals(f.parse(expected, ZoneOffset::from), offset);
 106 
 107             f = new DateTimeFormatterBuilder().appendPattern("OOOO").toFormatter(locale);
 108             assertEquals(f.format(odt), expected);
 109             assertEquals(f.format(zdt), expected);
 110             assertEquals(f.parse(expected, ZoneOffset::from), offset);
 111         }
 112 
 113         if (style == TextStyle.SHORT) {
 114             f = new DateTimeFormatterBuilder().appendPattern("O").toFormatter(locale);
 115             assertEquals(f.format(odt), expected);
 116             assertEquals(f.format(zdt), expected);
 117             assertEquals(f.parse(expected, ZoneOffset::from), offset);
 118         }
 119         
 120     }
 121 
 122 }