1 /*
   2  * Copyright (c) 2010, 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");
  36     static SimpleDateFormat ywdFormat = new SimpleDateFormat("YYYY-'W'ww-u");
  37     static {
  38         ymdFormat.setCalendar(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 
  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 
  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 
 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
 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 
 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         jcal.setFirstDayOfWeek(MONDAY);
 141         jcal.setMinimalDaysInFirstWeek(4);
 142         SimpleDateFormat sdf = new SimpleDateFormat("Y-'W'ww-u");
 143         sdf.setCalendar(jcal);
 144         Date d = sdf.parse("21-W01-3"); // 2008-12-31 == H20-12-31
 145         GregorianCalendar gcal = newCalendar();
 146         gcal.setTime(d);
 147         if (gcal.get(YEAR) != 2008
 148             || gcal.get(MONTH) != DECEMBER
 149             || gcal.get(DAY_OF_MONTH) != 31) {
 150             String s = String.format("noWeekDateSupport: got %04d-%02d-%02d, expected 2008-12-31%n",
 151                                      gcal.get(YEAR),
 152                                      gcal.get(MONTH)+1,
 153                                      gcal.get(DAY_OF_MONTH));
 154             throw new RuntimeException(s);
 155         }
 156     }
 157 
 158     private static GregorianCalendar newCalendar() {
 159         // Use GMT to avoid any surprises related DST transitions.
 160         GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
 161         // Setup the ISO 8601 compatible parameters
 162         cal.setFirstDayOfWeek(MONDAY);
 163         cal.setMinimalDaysInFirstWeek(4);
 164         return cal;
 165     }
 166 }