1 /*
2  * Copyright (c) 2010, 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 4267450
27  * @summary Unit test for week date support
28  */
29 
30 import java.text.*;
31 import java.util.*;
32 import static java.util.GregorianCalendar.*;
33 
34 public class WeekDateTest {
35     static SimpleDateFormat ymdFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
36     static SimpleDateFormat ywdFormat = new SimpleDateFormat("YYYY-'W'ww-u", Locale.US);
37     static {
newCalendar()38         ymdFormat.setCalendar(newCalendar());
newCalendar()39         ywdFormat.setCalendar(newCalendar());
40     }
41 
42     // Round-trip Data
43     static final String[][] roundTripData = {
44         { "2005-01-01", "2004-W53-6" },
45         { "2005-01-02", "2004-W53-7" },
46         { "2005-12-31", "2005-W52-6" },
47         { "2007-01-01", "2007-W01-1" },
48         { "2007-12-30", "2007-W52-7" },
49         { "2007-12-31", "2008-W01-1" },
50         { "2008-01-01", "2008-W01-2" },
51         { "2008-12-29", "2009-W01-1" },
52         { "2008-12-31", "2009-W01-3" },
53         { "2009-01-01", "2009-W01-4" },
54         { "2009-12-31", "2009-W53-4" },
55         { "2010-01-03", "2009-W53-7" },
56         { "2009-12-31", "2009-W53-4" },
57         { "2010-01-01", "2009-W53-5" },
58         { "2010-01-02", "2009-W53-6" },
59         { "2010-01-03", "2009-W53-7" },
60         { "2008-12-28", "2008-W52-7" },
61         { "2008-12-29", "2009-W01-1" },
62         { "2008-12-30", "2009-W01-2" },
63         { "2008-12-31", "2009-W01-3" },
64         { "2009-01-01", "2009-W01-4" },
65         { "2009-01-01", "2009-W01-4" },
66     };
67 
68     // Data for leniency test
69     static final String[][] leniencyData = {
70         { "2008-12-28", "2009-W01-0" },
71         { "2010-01-04", "2009-W53-8" },
72         { "2008-12-29", "2008-W53-1" },
73     };
74 
75     static final String[] invalidData = {
76         "2010-W00-1",
77         "2010-W55-1",
78         "2010-W03-0",
79         "2010-W04-8",
80         "2010-W04-19"
81     };
82 
main(String[] args)83     public static void main(String[] args) throws Exception {
84         formatTest(roundTripData);
85         parseTest(roundTripData);
86         parseTest(leniencyData);
87         nonLenientTest(invalidData);
88         noWeekDateSupport();
89     }
90 
formatTest(String[][] data)91     private static void formatTest(String[][] data) throws Exception {
92         for (String[] dates : data) {
93             String regularDate = dates[0];
94             String weekDate = dates[1];
95             Date date = null;
96             date = ymdFormat.parse(regularDate);
97             String s = ywdFormat.format(date);
98             if (!s.equals(weekDate)) {
99                 throw new RuntimeException("format: got="+s+", expecetd="+weekDate);
100             }
101         }
102     }
103 
parseTest(String[][] data)104     private static void parseTest(String[][] data) throws Exception {
105         for (String[] dates : data) {
106             String regularDate = dates[0];
107             String weekDate = dates[1];
108             Date date1 = null, date2 = null;
109             date1 = ymdFormat.parse(regularDate);
110             date2 = ywdFormat.parse(weekDate);
111             if (!date1.equals(date2)) {
112                 System.err.println(regularDate + ": date1 = " + date1);
113                 System.err.println(weekDate + ": date2 = " + date2);
114                 throw new RuntimeException("parse: date1 != date2");
115             }
116         }
117     }
118 
119 
120     // Non-lenient mode test
nonLenientTest(String[] data)121     private static void nonLenientTest(String[] data) {
122         ywdFormat.setLenient(false);
123         for (String date : data) {
124             try {
125                 Date d = ywdFormat.parse(date);
126                 throw new RuntimeException("No ParseException thrown with " + date);
127             } catch (ParseException e) {
128                 // OK
129             }
130         }
131         ywdFormat.setLenient(true);
132     }
133 
134 
noWeekDateSupport()135     private static void noWeekDateSupport() throws Exception {
136         // Tests with Japanese Imperial Calendar that doesn't support week dates.
137         Calendar jcal = Calendar.getInstance(TimeZone.getTimeZone("GMT"),
138                                              new Locale("ja", "JP", "JP"));
139 
140         String format = "2-W01-2"; // 2019-12-31 == R1-12-31
141         int expectedYear = 2019;
142         // Check the current era, Heisei or Reiwa
143         if (System.currentTimeMillis() < 1556668800000L) {
144             format = "21-W01-3"; // 2008-12-31 == H20-12-31
145             expectedYear = 2008;
146         }
147         jcal.setFirstDayOfWeek(MONDAY);
148         jcal.setMinimalDaysInFirstWeek(4);
149         SimpleDateFormat sdf = new SimpleDateFormat("Y-'W'ww-u");
150         sdf.setCalendar(jcal);
151         Date d = sdf.parse(format);
152         GregorianCalendar gcal = newCalendar();
153         gcal.setTime(d);
154         if (gcal.get(YEAR) != expectedYear
155             || gcal.get(MONTH) != DECEMBER
156             || gcal.get(DAY_OF_MONTH) != 31) {
157             String s = String.format("noWeekDateSupport: got %04d-%02d-%02d, expected %4d-12-31%n",
158                                      gcal.get(YEAR),
159                                      gcal.get(MONTH)+1,
160                                      gcal.get(DAY_OF_MONTH),
161                                      expectedYear);
162             throw new RuntimeException(s);
163         }
164     }
165 
newCalendar()166     private static GregorianCalendar newCalendar() {
167         // Use GMT to avoid any surprises related DST transitions.
168         GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
169         // Setup the ISO 8601 compatible parameters
170         cal.setFirstDayOfWeek(MONDAY);
171         cal.setMinimalDaysInFirstWeek(4);
172         return cal;
173     }
174 }
175