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.temporal.ChronoField.DAY_OF_MONTH; 60 import static java.time.temporal.ChronoField.DAY_OF_WEEK; 61 import static java.time.temporal.ChronoField.DAY_OF_YEAR; 62 import static java.time.temporal.ChronoField.MONTH_OF_YEAR; 63 import static java.time.temporal.ChronoField.YEAR; 64 import static org.testng.Assert.assertEquals; 65 import static org.testng.Assert.assertSame; 66 67 import java.io.IOException; 68 import java.time.DayOfWeek; 69 import java.time.LocalDate; 70 import java.time.format.DateTimeFormatter; 71 import java.time.format.DateTimeFormatterBuilder; 72 import java.time.temporal.TemporalField; 73 import java.time.temporal.ValueRange; 74 import java.time.temporal.WeekFields; 75 76 import org.testng.annotations.DataProvider; 77 import org.testng.annotations.Test; 78 import tck.java.time.AbstractTCKTest; 79 80 /** 81 * Test WeekFields. 82 */ 83 @Test 84 public class TCKWeekFields extends AbstractTCKTest { 85 86 @Test(dataProvider="weekFields") 87 public void test_of_DayOfWeek_int_singleton(DayOfWeek firstDayOfWeek, int minDays) { 88 WeekFields week = WeekFields.of(firstDayOfWeek, minDays); 89 assertEquals(week.getFirstDayOfWeek(), firstDayOfWeek, "Incorrect firstDayOfWeek"); 90 assertEquals(week.getMinimalDaysInFirstWeek(), minDays, "Incorrect MinimalDaysInFirstWeek"); 91 assertSame(WeekFields.of(firstDayOfWeek, minDays), week); 92 } 93 94 //----------------------------------------------------------------------- 95 @Test 96 public void test_dayOfWeekField_simpleGet() { 97 LocalDate date = LocalDate.of(2000, 1, 10); // Known to be ISO Monday 98 assertEquals(date.get(WeekFields.ISO.dayOfWeek()), 1); 99 assertEquals(date.get(WeekFields.of(DayOfWeek.MONDAY, 1).dayOfWeek()), 1); 100 assertEquals(date.get(WeekFields.of(DayOfWeek.MONDAY, 7).dayOfWeek()), 1); 101 assertEquals(date.get(WeekFields.SUNDAY_START.dayOfWeek()), 2); 102 assertEquals(date.get(WeekFields.of(DayOfWeek.SUNDAY, 1).dayOfWeek()), 2); 103 assertEquals(date.get(WeekFields.of(DayOfWeek.SUNDAY, 7).dayOfWeek()), 2); 104 assertEquals(date.get(WeekFields.of(DayOfWeek.SATURDAY, 1).dayOfWeek()), 3); 105 assertEquals(date.get(WeekFields.of(DayOfWeek.FRIDAY, 1).dayOfWeek()), 4); 106 assertEquals(date.get(WeekFields.of(DayOfWeek.TUESDAY, 1).dayOfWeek()), 7); 107 } 108 109 @Test 110 public void test_dayOfWeekField_simpleSet() { 111 LocalDate date = LocalDate.of(2000, 1, 10); // Known to be ISO Monday 112 assertEquals(date.with(WeekFields.ISO.dayOfWeek(), 2), LocalDate.of(2000, 1, 11)); 113 assertEquals(date.with(WeekFields.ISO.dayOfWeek(), 7), LocalDate.of(2000, 1, 16)); 114 115 assertEquals(date.with(WeekFields.SUNDAY_START.dayOfWeek(), 3), LocalDate.of(2000, 1, 11)); 116 assertEquals(date.with(WeekFields.SUNDAY_START.dayOfWeek(), 7), LocalDate.of(2000, 1, 15)); 117 118 assertEquals(date.with(WeekFields.of(DayOfWeek.SATURDAY, 1).dayOfWeek(), 4), LocalDate.of(2000, 1, 11)); 119 assertEquals(date.with(WeekFields.of(DayOfWeek.TUESDAY, 1).dayOfWeek(), 1), LocalDate.of(2000, 1, 4)); 120 } 121 122 @Test(dataProvider="weekFields") 123 public void test_dayOfWeekField(DayOfWeek firstDayOfWeek, int minDays) { 124 LocalDate day = LocalDate.of(2000, 1, 10); // Known to be ISO Monday 125 WeekFields week = WeekFields.of(firstDayOfWeek, minDays); 126 TemporalField f = week.dayOfWeek(); 127 //System.out.printf(" Week: %s; field: %s%n", week, f); 128 129 for (int i = 1; i <= 7; i++) { 130 //System.out.printf(" ISO Dow: %s, WeekDOW ordinal: %s%n", day.getDayOfWeek(), day.get(f)); 131 assertEquals(day.get(f), (7 + day.getDayOfWeek().getValue() - firstDayOfWeek.getValue()) % 7 + 1); 132 day = day.plusDays(1); 133 } 134 } 135 136 @Test(dataProvider="weekFields") 137 public void test_weekOfMonthField(DayOfWeek firstDayOfWeek, int minDays) { 138 LocalDate day = LocalDate.of(2012, 12, 31); // Known to be ISO Monday 139 WeekFields week = WeekFields.of(firstDayOfWeek, minDays); 140 TemporalField dowField = week.dayOfWeek(); 141 TemporalField womField = week.weekOfMonth(); 142 //System.err.printf("%n Week: %s; dowField: %s, domField: %s%n", week, dowField, womField); 143 144 DayOfWeek isoDOW = day.getDayOfWeek(); 145 int dow = (7 + isoDOW.getValue() - firstDayOfWeek.getValue()) % 7 + 1; 146 147 for (int i = 1; i <= 15; i++) { 148 int actualDOW = day.get(dowField); 149 int actualWOM = day.get(womField); 150 151 // Verify that the combination of day of week and week of month can be used 152 // to reconstruct the same date. 153 LocalDate day1 = day.withDayOfMonth(1); 154 int offset = - (day1.get(dowField) - 1); 155 //System.err.printf(" refDay: %s%n", day1.plusDays(offset)); 156 int week1 = day1.get(womField); 157 if (week1 == 0) { 158 // week of the 1st is partial; start with first full week 159 offset += 7; 160 } 161 //System.err.printf(" refDay2: %s, offset: %d, week1: %d%n", day1.plusDays(offset), offset, week1); 162 offset += actualDOW - 1; 163 //System.err.printf(" refDay3: %s%n", day1.plusDays(offset)); 164 offset += (actualWOM - 1) * 7; 165 //System.err.printf(" refDay4: %s%n", day1.plusDays(offset)); 166 LocalDate result = day1.plusDays(offset); 167 168 if (!day.equals(result)) { 169 System.err.printf("FAIL ISO Dow: %s, offset: %s, actualDOW: %s, actualWOM: %s, expected: %s, result: %s%n", 170 day.getDayOfWeek(), offset, actualDOW, actualWOM, day, result); 171 } 172 assertEquals(result, day, "Incorrect dayOfWeek or weekOfMonth: " 173 + String.format("%s, ISO Dow: %s, offset: %s, actualDOW: %s, actualWOM: %s, expected: %s, result: %s%n", 174 week, day.getDayOfWeek(), offset, actualDOW, actualWOM, day, result)); 175 day = day.plusDays(1); 176 } 177 } 178 179 @Test(dataProvider="weekFields") 180 public void test_weekOfYearField(DayOfWeek firstDayOfWeek, int minDays) { 181 LocalDate day = LocalDate.of(2012, 12, 31); // Known to be ISO Monday 182 WeekFields week = WeekFields.of(firstDayOfWeek, minDays); 183 TemporalField dowField = week.dayOfWeek(); 184 TemporalField woyField = week.weekOfYear(); 185 //System.err.printf("%n Year: %s; dowField: %s, woyField: %s%n", week, dowField, woyField); 186 187 DayOfWeek isoDOW = day.getDayOfWeek(); 188 int dow = (7 + isoDOW.getValue() - firstDayOfWeek.getValue()) % 7 + 1; 189 190 for (int i = 1; i <= 15; i++) { 191 int actualDOW = day.get(dowField); 192 int actualWOY = day.get(woyField); 193 194 // Verify that the combination of day of week and week of month can be used 195 // to reconstruct the same date. 196 LocalDate day1 = day.withDayOfYear(1); 197 int offset = - (day1.get(dowField) - 1); 198 //System.err.printf(" refDay: %s%n", day1.plusDays(offset)); 199 int week1 = day1.get(woyField); 200 if (week1 == 0) { 201 // week of the 1st is partial; start with first full week 202 offset += 7; 203 } 204 //System.err.printf(" refDay2: %s, offset: %d, week1: %d%n", day1.plusDays(offset), offset, week1); 205 offset += actualDOW - 1; 206 //System.err.printf(" refDay3: %s%n", day1.plusDays(offset)); 207 offset += (actualWOY - 1) * 7; 208 //System.err.printf(" refDay4: %s%n", day1.plusDays(offset)); 209 LocalDate result = day1.plusDays(offset); 210 211 212 if (!day.equals(result)) { 213 System.err.printf("FAIL ISO Dow: %s, offset: %s, actualDOW: %s, actualWOY: %s, expected: %s, result: %s%n", 214 day.getDayOfWeek(), offset, actualDOW, actualWOY, day, result); 215 } 216 assertEquals(result, day, "Incorrect dayOfWeek or weekOfYear " 217 + String.format("%s, ISO Dow: %s, offset: %s, actualDOW: %s, actualWOM: %s, expected: %s, result: %s%n", 218 week, day.getDayOfWeek(), offset, actualDOW, actualWOY, day, result)); 219 day = day.plusDays(1); 220 } 221 } 222 223 @Test(dataProvider="weekFields") 224 public void test_fieldRanges(DayOfWeek firstDayOfWeek, int minDays) { 225 WeekFields weekDef = WeekFields.of(firstDayOfWeek, minDays); 226 TemporalField womField = weekDef.weekOfMonth(); 227 TemporalField woyField = weekDef.weekOfYear(); 228 229 LocalDate day = LocalDate.of(2012, 11, 30); 230 LocalDate endDay = LocalDate.of(2013, 1, 2); 231 while (day.isBefore(endDay)) { 232 LocalDate last = day.with(DAY_OF_MONTH, day.lengthOfMonth()); 233 int lastWOM = last.get(womField); 234 LocalDate first = day.with(DAY_OF_MONTH, 1); 235 int firstWOM = first.get(womField); 236 ValueRange rangeWOM = day.range(womField); 237 assertEquals(rangeWOM.getMinimum(), firstWOM, 238 "Range min should be same as WeekOfMonth for first day of month: " 239 + first + ", " + weekDef); 240 assertEquals(rangeWOM.getMaximum(), lastWOM, 241 "Range max should be same as WeekOfMonth for last day of month: " 242 + last + ", " + weekDef); 243 244 last = day.with(DAY_OF_YEAR, day.lengthOfYear()); 245 int lastWOY = last.get(woyField); 246 first = day.with(DAY_OF_YEAR, 1); 247 int firstWOY = first.get(woyField); 248 ValueRange rangeWOY = day.range(woyField); 249 assertEquals(rangeWOY.getMinimum(), firstWOY, 250 "Range min should be same as WeekOfYear for first day of Year: " 251 + day + ", " + weekDef); 252 assertEquals(rangeWOY.getMaximum(), lastWOY, 253 "Range max should be same as WeekOfYear for last day of Year: " 254 + day + ", " + weekDef); 255 256 day = day.plusDays(1); 257 } 258 } 259 260 //----------------------------------------------------------------------- 261 // withDayOfWeek() 262 //----------------------------------------------------------------------- 263 @Test(dataProvider="weekFields") 264 public void test_withDayOfWeek(DayOfWeek firstDayOfWeek, int minDays) { 265 LocalDate day = LocalDate.of(2012, 12, 15); // Safely in the middle of a month 266 WeekFields week = WeekFields.of(firstDayOfWeek, minDays); 267 TemporalField dowField = week.dayOfWeek(); 268 TemporalField womField = week.weekOfMonth(); 269 TemporalField woyField = week.weekOfYear(); 270 271 int wom = day.get(womField); 272 int woy = day.get(woyField); 273 for (int dow = 1; dow <= 7; dow++) { 274 LocalDate result = day.with(dowField, dow); 275 if (result.get(dowField) != dow) { 276 System.err.printf(" DOW actual: %d, expected: %d, week:%s%n", 277 result.get(dowField), dow, week); 278 } 279 if (result.get(womField) != wom) { 280 System.err.printf(" WOM actual: %d, expected: %d, week:%s%n", 281 result.get(womField), wom, week); 282 } 283 if (result.get(woyField) != woy) { 284 System.err.printf(" WOY actual: %d, expected: %d, week:%s%n", 285 result.get(woyField), woy, week); 286 } 287 assertEquals(result.get(dowField), dow, String.format("Incorrect new Day of week: %s", result)); 288 assertEquals(result.get(womField), wom, "Week of Month should not change"); 289 assertEquals(result.get(woyField), woy, "Week of Year should not change"); 290 } 291 } 292 293 //----------------------------------------------------------------------- 294 @Test(dataProvider="weekFields") 295 public void test_parse_resolve_localizedWom(DayOfWeek firstDayOfWeek, int minDays) { 296 LocalDate date = LocalDate.of(2012, 12, 15); 297 WeekFields week = WeekFields.of(firstDayOfWeek, minDays); 298 TemporalField womField = week.weekOfMonth(); 299 300 for (int i = 1; i <= 60; i++) { 301 // Test that with dayOfWeek and Week of month it computes the date 302 DateTimeFormatter f = new DateTimeFormatterBuilder() 303 .appendValue(YEAR).appendLiteral('-') 304 .appendValue(MONTH_OF_YEAR).appendLiteral('-') 305 .appendValue(womField).appendLiteral('-') 306 .appendValue(DAY_OF_WEEK).toFormatter(); 307 String str = date.getYear() + "-" + date.getMonthValue() + "-" + 308 date.get(womField) + "-" + date.get(DAY_OF_WEEK); 309 LocalDate parsed = LocalDate.parse(str, f); 310 assertEquals(parsed, date, " ::" + str + "::" + i); 311 312 date = date.plusDays(1); 313 } 314 } 315 316 @Test(dataProvider="weekFields") 317 public void test_parse_resolve_localizedWomDow(DayOfWeek firstDayOfWeek, int minDays) { 318 LocalDate date = LocalDate.of(2012, 12, 15); 319 WeekFields week = WeekFields.of(firstDayOfWeek, minDays); 320 TemporalField dowField = week.dayOfWeek(); 321 TemporalField womField = week.weekOfMonth(); 322 323 for (int i = 1; i <= 15; i++) { 324 // Test that with dayOfWeek and Week of month it computes the date 325 DateTimeFormatter f = new DateTimeFormatterBuilder() 326 .appendValue(YEAR).appendLiteral('-') 327 .appendValue(MONTH_OF_YEAR).appendLiteral('-') 328 .appendValue(womField).appendLiteral('-') 329 .appendValue(dowField).toFormatter(); 330 String str = date.getYear() + "-" + date.getMonthValue() + "-" + 331 date.get(womField) + "-" + date.get(dowField); 332 LocalDate parsed = LocalDate.parse(str, f); 333 assertEquals(parsed, date, " :: " + str + " " + i); 334 335 date = date.plusDays(1); 336 } 337 } 338 339 @Test(dataProvider="weekFields") 340 public void test_parse_resolve_localizedWoy(DayOfWeek firstDayOfWeek, int minDays) { 341 LocalDate date = LocalDate.of(2012, 12, 15); 342 WeekFields week = WeekFields.of(firstDayOfWeek, minDays); 343 TemporalField woyField = week.weekOfYear(); 344 345 for (int i = 1; i <= 60; i++) { 346 // Test that with dayOfWeek and Week of month it computes the date 347 DateTimeFormatter f = new DateTimeFormatterBuilder() 348 .appendValue(YEAR).appendLiteral('-') 349 .appendValue(MONTH_OF_YEAR).appendLiteral('-') 350 .appendValue(woyField).appendLiteral('-') 351 .appendValue(DAY_OF_WEEK).toFormatter(); 352 String str = date.getYear() + "-" + date.getMonthValue() + "-" + 353 date.get(woyField) + "-" + date.get(DAY_OF_WEEK); 354 LocalDate parsed = LocalDate.parse(str, f); 355 assertEquals(parsed, date, " :: " + str + " " + i); 356 357 date = date.plusDays(1); 358 } 359 } 360 361 @Test(dataProvider="weekFields") 362 public void test_parse_resolve_localizedWoyDow(DayOfWeek firstDayOfWeek, int minDays) { 363 LocalDate date = LocalDate.of(2012, 12, 15); 364 WeekFields week = WeekFields.of(firstDayOfWeek, minDays); 365 TemporalField dowField = week.dayOfWeek(); 366 TemporalField woyField = week.weekOfYear(); 367 368 for (int i = 1; i <= 60; i++) { 369 // Test that with dayOfWeek and Week of month it computes the date 370 DateTimeFormatter f = new DateTimeFormatterBuilder() 371 .appendValue(YEAR).appendLiteral('-') 372 .appendValue(MONTH_OF_YEAR).appendLiteral('-') 373 .appendValue(woyField).appendLiteral('-') 374 .appendValue(dowField).toFormatter(); 375 String str = date.getYear() + "-" + date.getMonthValue() + "-" + 376 date.get(woyField) + "-" + date.get(dowField); 377 LocalDate parsed = LocalDate.parse(str, f); 378 assertEquals(parsed, date, " :: " + str + " " + i); 379 380 date = date.plusDays(1); 381 } 382 } 383 384 //----------------------------------------------------------------------- 385 @Test(dataProvider="weekFields") 386 public void test_serializable_singleton(DayOfWeek firstDayOfWeek, int minDays) throws IOException, ClassNotFoundException { 387 WeekFields weekDef = WeekFields.of(firstDayOfWeek, minDays); 388 assertSerializableSame(weekDef); // spec state singleton 389 } 390 391 //----------------------------------------------------------------------- 392 @DataProvider(name="weekFields") 393 Object[][] data_weekFields() { 394 Object[][] objects = new Object[49][]; 395 int i = 0; 396 for (DayOfWeek firstDayOfWeek : DayOfWeek.values()) { 397 for (int minDays = 1; minDays <= 7; minDays++) { 398 objects[i++] = new Object[] {firstDayOfWeek, minDays}; 399 } 400 } 401 return objects; 402 } 403 404 }