1 /*
   2  * Copyright (c) 2012, 2013, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27  * Copyright (c) 2008-2012, Stephen Colebourne & Michael Nascimento Santos
  28  *
  29  * All rights reserved.
  30  *
  31  * Redistribution and use in source and binary forms, with or without
  32  * modification, are permitted provided that the following conditions are met:
  33  *
  34  *  * Redistributions of source code must retain the above copyright notice,
  35  *    this list of conditions and the following disclaimer.
  36  *
  37  *  * Redistributions in binary form must reproduce the above copyright notice,
  38  *    this list of conditions and the following disclaimer in the documentation
  39  *    and/or other materials provided with the distribution.
  40  *
  41  *  * Neither the name of JSR-310 nor the names of its contributors
  42  *    may be used to endorse or promote products derived from this software
  43  *    without specific prior written permission.
  44  *
  45  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  46  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  47  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  48  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  49  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  50  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  51  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  52  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  53  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  54  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  55  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  56  */
  57 package tck.java.time.temporal;
  58 
  59 import static java.time.DayOfWeek.FRIDAY;
  60 import static java.time.DayOfWeek.MONDAY;
  61 import static java.time.DayOfWeek.SATURDAY;
  62 import static java.time.DayOfWeek.SUNDAY;
  63 import static java.time.DayOfWeek.THURSDAY;
  64 import static java.time.DayOfWeek.TUESDAY;
  65 import static java.time.DayOfWeek.WEDNESDAY;
  66 import static java.time.temporal.ChronoField.DAY_OF_WEEK;
  67 import static java.time.temporal.ChronoField.YEAR;
  68 import static org.testng.Assert.assertEquals;
  69 
  70 import java.time.DayOfWeek;
  71 import java.time.LocalDate;
  72 import java.time.format.DateTimeFormatter;
  73 import java.time.format.DateTimeFormatterBuilder;
  74 import java.time.temporal.IsoFields;
  75 import java.time.temporal.ValueRange;
  76 
  77 import org.testng.annotations.DataProvider;
  78 import org.testng.annotations.Test;
  79 
  80 /**
  81  * Test.
  82  */
  83 @Test(groups={"tck"})
  84 public class TCKIsoFields {
  85 
  86     @DataProvider(name="quarter")
  87     Object[][] data_quarter() {
  88         return new Object[][] {
  89                 {LocalDate.of(1969, 12, 29), 90, 4},
  90                 {LocalDate.of(1969, 12, 30), 91, 4},
  91                 {LocalDate.of(1969, 12, 31), 92, 4},
  92 
  93                 {LocalDate.of(1970, 1, 1), 1, 1},
  94                 {LocalDate.of(1970, 1, 2), 2, 1},
  95                 {LocalDate.of(1970, 2, 28), 59, 1},
  96                 {LocalDate.of(1970, 3, 1), 60, 1},
  97                 {LocalDate.of(1970, 3, 31), 90, 1},
  98 
  99                 {LocalDate.of(1970, 4, 1), 1, 2},
 100                 {LocalDate.of(1970, 6, 30), 91, 2},
 101 
 102                 {LocalDate.of(1970, 7, 1), 1, 3},
 103                 {LocalDate.of(1970, 9, 30), 92, 3},
 104 
 105                 {LocalDate.of(1970, 10, 1), 1, 4},
 106                 {LocalDate.of(1970, 12, 31), 92, 4},
 107 
 108                 {LocalDate.of(1972, 2, 28), 59, 1},
 109                 {LocalDate.of(1972, 2, 29), 60, 1},
 110                 {LocalDate.of(1972, 3, 1), 61, 1},
 111                 {LocalDate.of(1972, 3, 31), 91, 1},
 112         };
 113     }
 114 
 115     //-----------------------------------------------------------------------
 116     // DAY_OF_QUARTER
 117     //-----------------------------------------------------------------------
 118     @Test(dataProvider="quarter")
 119     public void test_DOQ(LocalDate date, int doq, int qoy) {
 120         assertEquals(IsoFields.DAY_OF_QUARTER.getFrom(date), doq);
 121         assertEquals(date.get(IsoFields.DAY_OF_QUARTER), doq);
 122     }
 123 
 124     //-----------------------------------------------------------------------
 125     // QUARTER_OF_YEAR
 126     //-----------------------------------------------------------------------
 127     @Test(dataProvider="quarter")
 128     public void test_QOY(LocalDate date, int doq, int qoy) {
 129         assertEquals(IsoFields.QUARTER_OF_YEAR.getFrom(date), qoy);
 130         assertEquals(date.get(IsoFields.QUARTER_OF_YEAR), qoy);
 131     }
 132 
 133     //-----------------------------------------------------------------------
 134     // parse quarters
 135     //-----------------------------------------------------------------------
 136     @Test(dataProvider="quarter")
 137     public void test_parse_quarters(LocalDate date, int doq, int qoy) {
 138         DateTimeFormatter f = new DateTimeFormatterBuilder()
 139                 .appendValue(YEAR).appendLiteral('-')
 140                 .appendValue(IsoFields.QUARTER_OF_YEAR).appendLiteral('-')
 141                 .appendValue(IsoFields.DAY_OF_QUARTER).toFormatter();
 142         LocalDate parsed = LocalDate.parse(date.getYear() + "-" + qoy + "-" + doq, f);
 143         assertEquals(parsed, date);
 144     }
 145 
 146     //-----------------------------------------------------------------------
 147     // quarters between
 148     //-----------------------------------------------------------------------
 149     @DataProvider(name="quartersBetween")
 150     Object[][] data_quartersBetween() {
 151         return new Object[][] {
 152                 {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 1), 0},
 153                 {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 1, 2), 0},
 154                 {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 2, 1), 0},
 155                 {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 3, 1), 0},
 156                 {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 3, 31), 0},
 157                 {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 4, 1), 1},
 158                 {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 4, 2), 1},
 159                 {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 6, 30), 1},
 160                 {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 7, 1), 2},
 161                 {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 10, 1), 3},
 162                 {LocalDate.of(2000, 1, 1), LocalDate.of(2000, 12, 31), 3},
 163                 {LocalDate.of(2000, 1, 1), LocalDate.of(2001, 1, 1), 4},
 164                 {LocalDate.of(2000, 1, 1), LocalDate.of(2002, 1, 1), 8},
 165 
 166                 {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 12, 31), 0},
 167                 {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 10, 2), 0},
 168                 {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 10, 1), -1},
 169                 {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 7, 2), -1},
 170                 {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 7, 1), -2},
 171                 {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 4, 2), -2},
 172                 {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 4, 1), -3},
 173                 {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 1, 2), -3},
 174                 {LocalDate.of(2000, 1, 1), LocalDate.of(1999, 1, 1), -4},
 175                 {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 12, 31), -4},
 176                 {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 10, 2), -4},
 177                 {LocalDate.of(2000, 1, 1), LocalDate.of(1998, 10, 1), -5},
 178         };
 179     }
 180 
 181     @Test(dataProvider="quartersBetween")
 182     public void test_quarters_between(LocalDate start, LocalDate end, long expected) {
 183         assertEquals(IsoFields.QUARTER_YEARS.between(start, end), expected);
 184     }
 185 
 186     //-----------------------------------------------------------------------
 187     //-----------------------------------------------------------------------
 188     //-----------------------------------------------------------------------
 189     @DataProvider(name="week")
 190     Object[][] data_week() {
 191         return new Object[][] {
 192                 {LocalDate.of(1969, 12, 29), MONDAY, 1, 1970},
 193                 {LocalDate.of(2012, 12, 23), SUNDAY, 51, 2012},
 194                 {LocalDate.of(2012, 12, 24), MONDAY, 52, 2012},
 195                 {LocalDate.of(2012, 12, 27), THURSDAY, 52, 2012},
 196                 {LocalDate.of(2012, 12, 28), FRIDAY, 52, 2012},
 197                 {LocalDate.of(2012, 12, 29), SATURDAY, 52, 2012},
 198                 {LocalDate.of(2012, 12, 30), SUNDAY, 52, 2012},
 199                 {LocalDate.of(2012, 12, 31), MONDAY, 1, 2013},
 200                 {LocalDate.of(2013, 1, 1), TUESDAY, 1, 2013},
 201                 {LocalDate.of(2013, 1, 2), WEDNESDAY, 1, 2013},
 202                 {LocalDate.of(2013, 1, 6), SUNDAY, 1, 2013},
 203                 {LocalDate.of(2013, 1, 7), MONDAY, 2, 2013},
 204         };
 205     }
 206 
 207     //-----------------------------------------------------------------------
 208     // WEEK_OF_WEEK_BASED_YEAR
 209     //-----------------------------------------------------------------------
 210     @Test(dataProvider="week")
 211     public void test_WOWBY(LocalDate date, DayOfWeek dow, int week, int wby) {
 212         assertEquals(date.getDayOfWeek(), dow);
 213         assertEquals(IsoFields.WEEK_OF_WEEK_BASED_YEAR.getFrom(date), week);
 214         assertEquals(date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR), week);
 215     }
 216 
 217     //-----------------------------------------------------------------------
 218     // WEEK_BASED_YEAR
 219     //-----------------------------------------------------------------------
 220     @Test(dataProvider="week")
 221     public void test_WBY(LocalDate date, DayOfWeek dow, int week, int wby) {
 222         assertEquals(date.getDayOfWeek(), dow);
 223         assertEquals(IsoFields.WEEK_BASED_YEAR.getFrom(date), wby);
 224         assertEquals(date.get(IsoFields.WEEK_BASED_YEAR), wby);
 225     }
 226 
 227     //-----------------------------------------------------------------------
 228     // parse weeks
 229     //-----------------------------------------------------------------------
 230     @Test(dataProvider="week")
 231     public void test_parse_weeks(LocalDate date, DayOfWeek dow, int week, int wby) {
 232         DateTimeFormatter f = new DateTimeFormatterBuilder()
 233                 .appendValue(IsoFields.WEEK_BASED_YEAR).appendLiteral('-')
 234                 .appendValue(IsoFields.WEEK_OF_WEEK_BASED_YEAR).appendLiteral('-')
 235                 .appendValue(DAY_OF_WEEK).toFormatter();
 236         LocalDate parsed = LocalDate.parse(wby + "-" + week + "-" + dow.getValue(), f);
 237         assertEquals(parsed, date);
 238     }
 239 
 240     //-----------------------------------------------------------------------
 241     public void test_loop() {
 242         // loop round at least one 400 year cycle, including before 1970
 243         LocalDate date = LocalDate.of(1960, 1, 5);  // Tuseday of week 1 1960
 244         int year = 1960;
 245         int wby = 1960;
 246         int weekLen = 52;
 247         int week = 1;
 248         while (date.getYear() < 2400) {
 249             DayOfWeek loopDow = date.getDayOfWeek();
 250             if (date.getYear() != year) {
 251                 year = date.getYear();
 252             }
 253             if (loopDow == MONDAY) {
 254                 week++;
 255                 if ((week == 53 && weekLen == 52) || week == 54) {
 256                     week = 1;
 257                     LocalDate firstDayOfWeekBasedYear = date.plusDays(14).withDayOfYear(1);
 258                     DayOfWeek firstDay = firstDayOfWeekBasedYear.getDayOfWeek();
 259                     weekLen = (firstDay == THURSDAY || (firstDay == WEDNESDAY && firstDayOfWeekBasedYear.isLeapYear()) ? 53 : 52);
 260                     wby++;
 261                 }
 262             }
 263             assertEquals(IsoFields.WEEK_OF_WEEK_BASED_YEAR.rangeRefinedBy(date), ValueRange.of(1, weekLen), "Failed on " + date + " " + date.getDayOfWeek());
 264             assertEquals(IsoFields.WEEK_OF_WEEK_BASED_YEAR.getFrom(date), week, "Failed on " + date + " " + date.getDayOfWeek());
 265             assertEquals(date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR), week, "Failed on " + date + " " + date.getDayOfWeek());
 266             assertEquals(IsoFields.WEEK_BASED_YEAR.getFrom(date), wby, "Failed on " + date + " " + date.getDayOfWeek());
 267             assertEquals(date.get(IsoFields.WEEK_BASED_YEAR), wby, "Failed on " + date + " " + date.getDayOfWeek());
 268             date = date.plusDays(1);
 269         }
 270     }
 271 
 272     // TODO: more tests
 273 }