42 * and/or other materials provided with the distribution. 43 * 44 * * Neither the name of JSR-310 nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 49 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 50 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 51 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 52 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 53 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 54 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 55 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 56 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 57 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 58 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59 */ 60 package tck.java.time.format; 61 62 import static java.time.temporal.ChronoField.DAY_OF_MONTH; 63 import static java.time.temporal.ChronoField.HOUR_OF_DAY; 64 import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; 65 import static java.time.temporal.ChronoField.MONTH_OF_YEAR; 66 import static java.time.temporal.ChronoField.NANO_OF_SECOND; 67 import static java.time.temporal.ChronoField.YEAR; 68 import static org.testng.Assert.assertEquals; 69 70 import java.text.ParsePosition; 71 import java.time.LocalDate; 72 import java.time.YearMonth; 73 import java.time.ZoneOffset; 74 import java.time.format.DateTimeFormatter; 75 import java.time.format.DateTimeFormatterBuilder; 76 import java.time.format.SignStyle; 77 import java.time.format.TextStyle; 78 import java.time.temporal.Temporal; 79 import java.time.temporal.TemporalAccessor; 80 import java.util.HashMap; 81 import java.util.Locale; 82 import java.util.Map; 83 84 import org.testng.annotations.BeforeMethod; 85 import org.testng.annotations.DataProvider; 86 import org.testng.annotations.Test; 87 88 /** 89 * Test DateTimeFormatterBuilder. 90 */ 91 @Test 92 public class TCKDateTimeFormatterBuilder { 93 94 private DateTimeFormatterBuilder builder; 95 322 builder.appendText(null, new HashMap<>()); 323 } 324 325 @Test(expectedExceptions=NullPointerException.class) 326 public void test_appendTextMap_nullStyle() throws Exception { 327 builder.appendText(MONTH_OF_YEAR, (Map<Long, String>) null); 328 } 329 330 //----------------------------------------------------------------------- 331 //----------------------------------------------------------------------- 332 //----------------------------------------------------------------------- 333 @DataProvider(name="offsetPatterns") 334 Object[][] data_offsetPatterns() { 335 return new Object[][] { 336 {"+HH", 2, 0, 0, "+02"}, 337 {"+HH", -2, 0, 0, "-02"}, 338 {"+HH", 2, 30, 0, "+02"}, 339 {"+HH", 2, 0, 45, "+02"}, 340 {"+HH", 2, 30, 45, "+02"}, 341 342 {"+HHMM", 2, 0, 0, "+0200"}, 343 {"+HHMM", -2, 0, 0, "-0200"}, 344 {"+HHMM", 2, 30, 0, "+0230"}, 345 {"+HHMM", 2, 0, 45, "+0200"}, 346 {"+HHMM", 2, 30, 45, "+0230"}, 347 348 {"+HH:MM", 2, 0, 0, "+02:00"}, 349 {"+HH:MM", -2, 0, 0, "-02:00"}, 350 {"+HH:MM", 2, 30, 0, "+02:30"}, 351 {"+HH:MM", 2, 0, 45, "+02:00"}, 352 {"+HH:MM", 2, 30, 45, "+02:30"}, 353 354 {"+HHMMss", 2, 0, 0, "+0200"}, 355 {"+HHMMss", -2, 0, 0, "-0200"}, 356 {"+HHMMss", 2, 30, 0, "+0230"}, 357 {"+HHMMss", 2, 0, 45, "+020045"}, 358 {"+HHMMss", 2, 30, 45, "+023045"}, 359 360 {"+HH:MM:ss", 2, 0, 0, "+02:00"}, 361 {"+HH:MM:ss", -2, 0, 0, "-02:00"}, 362 {"+HH:MM:ss", 2, 30, 0, "+02:30"}, 363 {"+HH:MM:ss", 2, 0, 45, "+02:00:45"}, 364 {"+HH:MM:ss", 2, 30, 45, "+02:30:45"}, 365 366 {"+HHMMSS", 2, 0, 0, "+020000"}, 367 {"+HHMMSS", -2, 0, 0, "-020000"}, 368 {"+HHMMSS", 2, 30, 0, "+023000"}, 369 {"+HHMMSS", 2, 0, 45, "+020045"}, 370 {"+HHMMSS", 2, 30, 45, "+023045"}, 371 372 {"+HH:MM:SS", 2, 0, 0, "+02:00:00"}, 373 {"+HH:MM:SS", -2, 0, 0, "-02:00:00"}, 374 {"+HH:MM:SS", 2, 30, 0, "+02:30:00"}, 375 {"+HH:MM:SS", 2, 0, 45, "+02:00:45"}, 376 {"+HH:MM:SS", 2, 30, 45, "+02:30:45"}, 377 }; 378 } 379 380 @Test(dataProvider="offsetPatterns") 381 public void test_appendOffset_format(String pattern, int h, int m, int s, String expected) throws Exception { 382 builder.appendOffset(pattern, "Z"); 383 DateTimeFormatter f = builder.toFormatter(); 384 ZoneOffset offset = ZoneOffset.ofHoursMinutesSeconds(h, m, s); 385 assertEquals(f.format(offset), expected); 386 } 387 388 @Test(dataProvider="offsetPatterns") 389 public void test_appendOffset_parse(String pattern, int h, int m, int s, String expected) throws Exception { 390 builder.appendOffset(pattern, "Z"); 391 DateTimeFormatter f = builder.toFormatter(); 392 ZoneOffset parsed = f.parse(expected, ZoneOffset::from); 393 assertEquals(f.format(parsed), expected); 394 } 395 396 @DataProvider(name="badOffsetPatterns") 861 TemporalAccessor parsed = f.parseUnresolved("123056", pp); 862 assertEquals(pp.getErrorIndex(), -1); 863 assertEquals(pp.getIndex(), 6); 864 assertEquals(parsed.getLong(HOUR_OF_DAY), 12L); 865 assertEquals(parsed.getLong(MINUTE_OF_HOUR), 30L); 866 assertEquals(parsed.getLong(NANO_OF_SECOND), 560_000_000L); 867 } 868 869 @Test 870 public void test_adjacent_lenient_fractionFollows_0digit() throws Exception { 871 // succeeds because hour/min are fixed width 872 DateTimeFormatter f = builder.parseLenient().appendValue(HOUR_OF_DAY, 2).appendValue(MINUTE_OF_HOUR, 2).appendFraction(NANO_OF_SECOND, 3, 3, false).toFormatter(Locale.UK); 873 ParsePosition pp = new ParsePosition(0); 874 TemporalAccessor parsed = f.parseUnresolved("1230", pp); 875 assertEquals(pp.getErrorIndex(), -1); 876 assertEquals(pp.getIndex(), 4); 877 assertEquals(parsed.getLong(HOUR_OF_DAY), 12L); 878 assertEquals(parsed.getLong(MINUTE_OF_HOUR), 30L); 879 } 880 881 } | 42 * and/or other materials provided with the distribution. 43 * 44 * * Neither the name of JSR-310 nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 49 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 50 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 51 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 52 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 53 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 54 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 55 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 56 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 57 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 58 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59 */ 60 package tck.java.time.format; 61 62 import static java.time.format.DateTimeFormatter.BASIC_ISO_DATE; 63 import static java.time.temporal.ChronoField.DAY_OF_MONTH; 64 import static java.time.temporal.ChronoField.HOUR_OF_DAY; 65 import static java.time.temporal.ChronoField.MINUTE_OF_HOUR; 66 import static java.time.temporal.ChronoField.MONTH_OF_YEAR; 67 import static java.time.temporal.ChronoField.NANO_OF_SECOND; 68 import static java.time.temporal.ChronoField.OFFSET_SECONDS; 69 import static java.time.temporal.ChronoField.YEAR; 70 import static org.testng.Assert.assertEquals; 71 72 import java.text.ParsePosition; 73 import java.time.LocalDate; 74 import java.time.YearMonth; 75 import java.time.ZoneOffset; 76 import java.time.format.DateTimeFormatter; 77 import java.time.format.DateTimeFormatterBuilder; 78 import java.time.format.DateTimeParseException; 79 import java.time.format.SignStyle; 80 import java.time.format.TextStyle; 81 import java.time.temporal.Temporal; 82 import java.time.temporal.TemporalAccessor; 83 import java.util.HashMap; 84 import java.util.Locale; 85 import java.util.Map; 86 87 import org.testng.annotations.BeforeMethod; 88 import org.testng.annotations.DataProvider; 89 import org.testng.annotations.Test; 90 91 /** 92 * Test DateTimeFormatterBuilder. 93 */ 94 @Test 95 public class TCKDateTimeFormatterBuilder { 96 97 private DateTimeFormatterBuilder builder; 98 325 builder.appendText(null, new HashMap<>()); 326 } 327 328 @Test(expectedExceptions=NullPointerException.class) 329 public void test_appendTextMap_nullStyle() throws Exception { 330 builder.appendText(MONTH_OF_YEAR, (Map<Long, String>) null); 331 } 332 333 //----------------------------------------------------------------------- 334 //----------------------------------------------------------------------- 335 //----------------------------------------------------------------------- 336 @DataProvider(name="offsetPatterns") 337 Object[][] data_offsetPatterns() { 338 return new Object[][] { 339 {"+HH", 2, 0, 0, "+02"}, 340 {"+HH", -2, 0, 0, "-02"}, 341 {"+HH", 2, 30, 0, "+02"}, 342 {"+HH", 2, 0, 45, "+02"}, 343 {"+HH", 2, 30, 45, "+02"}, 344 345 {"+HHmm", 2, 0, 0, "+02"}, 346 {"+HHmm", -2, 0, 0, "-02"}, 347 {"+HHmm", 2, 30, 0, "+0230"}, 348 {"+HHmm", 2, 0, 45, "+02"}, 349 {"+HHmm", 2, 30, 45, "+0230"}, 350 351 {"+HH:mm", 2, 0, 0, "+02"}, 352 {"+HH:mm", -2, 0, 0, "-02"}, 353 {"+HH:mm", 2, 30, 0, "+02:30"}, 354 {"+HH:mm", 2, 0, 45, "+02"}, 355 {"+HH:mm", 2, 30, 45, "+02:30"}, 356 357 {"+HHMM", 2, 0, 0, "+0200"}, 358 {"+HHMM", -2, 0, 0, "-0200"}, 359 {"+HHMM", 2, 30, 0, "+0230"}, 360 {"+HHMM", 2, 0, 45, "+0200"}, 361 {"+HHMM", 2, 30, 45, "+0230"}, 362 363 {"+HH:MM", 2, 0, 0, "+02:00"}, 364 {"+HH:MM", -2, 0, 0, "-02:00"}, 365 {"+HH:MM", 2, 30, 0, "+02:30"}, 366 {"+HH:MM", 2, 0, 45, "+02:00"}, 367 {"+HH:MM", 2, 30, 45, "+02:30"}, 368 369 {"+HHMMss", 2, 0, 0, "+0200"}, 370 {"+HHMMss", -2, 0, 0, "-0200"}, 371 {"+HHMMss", 2, 30, 0, "+0230"}, 372 {"+HHMMss", 2, 0, 45, "+020045"}, 373 {"+HHMMss", 2, 30, 45, "+023045"}, 374 375 {"+HH:MM:ss", 2, 0, 0, "+02:00"}, 376 {"+HH:MM:ss", -2, 0, 0, "-02:00"}, 377 {"+HH:MM:ss", 2, 30, 0, "+02:30"}, 378 {"+HH:MM:ss", 2, 0, 45, "+02:00:45"}, 379 {"+HH:MM:ss", 2, 30, 45, "+02:30:45"}, 380 381 {"+HHMMSS", 2, 0, 0, "+020000"}, 382 {"+HHMMSS", -2, 0, 0, "-020000"}, 383 {"+HHMMSS", 2, 30, 0, "+023000"}, 384 {"+HHMMSS", 2, 0, 45, "+020045"}, 385 {"+HHMMSS", 2, 30, 45, "+023045"}, 386 387 {"+HH:MM:SS", 2, 0, 0, "+02:00:00"}, 388 {"+HH:MM:SS", -2, 0, 0, "-02:00:00"}, 389 {"+HH:MM:SS", 2, 30, 0, "+02:30:00"}, 390 {"+HH:MM:SS", 2, 0, 45, "+02:00:45"}, 391 {"+HH:MM:SS", 2, 30, 45, "+02:30:45"}, 392 393 {"+HHmmss", 2, 0, 0, "+02"}, 394 {"+HHmmss", -2, 0, 0, "-02"}, 395 {"+HHmmss", 2, 30, 0, "+0230"}, 396 {"+HHmmss", 2, 0, 45, "+020045"}, 397 {"+HHmmss", 2, 30, 45, "+023045"}, 398 399 {"+HH:mm:ss", 2, 0, 0, "+02"}, 400 {"+HH:mm:ss", -2, 0, 0, "-02"}, 401 {"+HH:mm:ss", 2, 30, 0, "+02:30"}, 402 {"+HH:mm:ss", 2, 0, 45, "+02:00:45"}, 403 {"+HH:mm:ss", 2, 30, 45, "+02:30:45"}, 404 405 406 }; 407 } 408 409 @Test(dataProvider="offsetPatterns") 410 public void test_appendOffset_format(String pattern, int h, int m, int s, String expected) throws Exception { 411 builder.appendOffset(pattern, "Z"); 412 DateTimeFormatter f = builder.toFormatter(); 413 ZoneOffset offset = ZoneOffset.ofHoursMinutesSeconds(h, m, s); 414 assertEquals(f.format(offset), expected); 415 } 416 417 @Test(dataProvider="offsetPatterns") 418 public void test_appendOffset_parse(String pattern, int h, int m, int s, String expected) throws Exception { 419 builder.appendOffset(pattern, "Z"); 420 DateTimeFormatter f = builder.toFormatter(); 421 ZoneOffset parsed = f.parse(expected, ZoneOffset::from); 422 assertEquals(f.format(parsed), expected); 423 } 424 425 @DataProvider(name="badOffsetPatterns") 890 TemporalAccessor parsed = f.parseUnresolved("123056", pp); 891 assertEquals(pp.getErrorIndex(), -1); 892 assertEquals(pp.getIndex(), 6); 893 assertEquals(parsed.getLong(HOUR_OF_DAY), 12L); 894 assertEquals(parsed.getLong(MINUTE_OF_HOUR), 30L); 895 assertEquals(parsed.getLong(NANO_OF_SECOND), 560_000_000L); 896 } 897 898 @Test 899 public void test_adjacent_lenient_fractionFollows_0digit() throws Exception { 900 // succeeds because hour/min are fixed width 901 DateTimeFormatter f = builder.parseLenient().appendValue(HOUR_OF_DAY, 2).appendValue(MINUTE_OF_HOUR, 2).appendFraction(NANO_OF_SECOND, 3, 3, false).toFormatter(Locale.UK); 902 ParsePosition pp = new ParsePosition(0); 903 TemporalAccessor parsed = f.parseUnresolved("1230", pp); 904 assertEquals(pp.getErrorIndex(), -1); 905 assertEquals(pp.getIndex(), 4); 906 assertEquals(parsed.getLong(HOUR_OF_DAY), 12L); 907 assertEquals(parsed.getLong(MINUTE_OF_HOUR), 30L); 908 } 909 910 @Test 911 public void test_lenient_offset_parse() { 912 assertEquals(new DateTimeFormatterBuilder().parseLenient().appendOffsetId().toFormatter().parse("+01").get(OFFSET_SECONDS), 913 3600); 914 assertEquals(new DateTimeFormatterBuilder().parseLenient().appendOffset("+HH:MM:ss", "Z").toFormatter().parse("+01").get(OFFSET_SECONDS), 915 3600); 916 assertEquals(new DateTimeFormatterBuilder().parseLenient().appendOffset("+HHMMss", "Z").toFormatter().parse("+01").get(OFFSET_SECONDS), 917 3600); 918 } 919 920 @Test(expectedExceptions=DateTimeParseException.class) 921 public void test_strict_appendOffsetId() { 922 assertEquals(new DateTimeFormatterBuilder().appendOffsetId().toFormatter().parse("+01").get(OFFSET_SECONDS), 923 3600); 924 } 925 926 @Test(expectedExceptions=DateTimeParseException.class) 927 public void test_strict_appendOffset_1() { 928 assertEquals(new DateTimeFormatterBuilder().appendOffset("+HH:MM:ss", "Z").toFormatter().parse("+01").get(OFFSET_SECONDS), 929 3600); 930 } 931 932 @Test(expectedExceptions=DateTimeParseException.class) 933 public void test_strict_appendOffset_2() { 934 assertEquals(new DateTimeFormatterBuilder().appendOffset("+HHMMss", "Z").toFormatter().parse("+01").get(OFFSET_SECONDS), 935 3600); 936 } 937 938 @Test 939 public void test_basic_iso_date() { 940 assertEquals(BASIC_ISO_DATE.parse("20021231+01").get(OFFSET_SECONDS), 3600); 941 assertEquals(BASIC_ISO_DATE.parse("20021231+0101").get(OFFSET_SECONDS), 3660); 942 } 943 944 } |