test/java/time/test/java/time/format/TestZoneOffsetParser.java

Print this page




  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 test.java.time.format;
  61 
  62 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
  63 import static org.testng.Assert.assertEquals;
  64 import static org.testng.Assert.assertTrue;
  65 
  66 import java.text.ParsePosition;
  67 import java.time.ZoneOffset;
  68 import java.time.format.DateTimeBuilder;
  69 
  70 import org.testng.annotations.DataProvider;
  71 import org.testng.annotations.Test;
  72 
  73 /**
  74  * Test ZoneOffsetPrinterParser.
  75  */
  76 @Test(groups={"implementation"})
  77 public class TestZoneOffsetParser extends AbstractTestPrinterParser {
  78 
  79     //-----------------------------------------------------------------------
  80     @DataProvider(name="error")
  81     Object[][] data_error() {
  82         return new Object[][] {
  83             {"+HH:MM:ss", "Z", "hello", -1, IndexOutOfBoundsException.class},
  84             {"+HH:MM:ss", "Z", "hello", 6, IndexOutOfBoundsException.class},
  85         };
  86     }
  87 
  88     @Test(dataProvider="error")
  89     public void test_parse_error(String pattern, String noOffsetText, String text, int pos, Class<?> expected) {
  90         try {
  91             getFormatter(pattern, noOffsetText).parseToBuilder(text, new ParsePosition(pos));
  92         } catch (RuntimeException ex) {
  93             assertTrue(expected.isInstance(ex));
  94         }
  95     }
  96 
  97     //-----------------------------------------------------------------------
  98     public void test_parse_exactMatch_UTC() throws Exception {
  99         ParsePosition pos = new ParsePosition(0);
 100         DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("Z", pos);
 101         assertEquals(pos.getIndex(), 1);
 102         assertParsed(dtb, ZoneOffset.UTC);
 103     }
 104 
 105     public void test_parse_startStringMatch_UTC() throws Exception {
 106         ParsePosition pos = new ParsePosition(0);
 107         DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("ZOTHER", pos);
 108         assertEquals(pos.getIndex(), 1);
 109         assertParsed(dtb, ZoneOffset.UTC);
 110     }
 111 
 112     public void test_parse_midStringMatch_UTC() throws Exception {
 113         ParsePosition pos = new ParsePosition(5);
 114         DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("OTHERZOTHER", pos);
 115         assertEquals(pos.getIndex(), 6);
 116         assertParsed(dtb, ZoneOffset.UTC);
 117     }
 118 
 119     public void test_parse_endStringMatch_UTC() throws Exception {
 120         ParsePosition pos = new ParsePosition(5);
 121         DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("OTHERZ", pos);
 122         assertEquals(pos.getIndex(), 6);
 123         assertParsed(dtb, ZoneOffset.UTC);
 124     }
 125 
 126     //-----------------------------------------------------------------------
 127     public void test_parse_exactMatch_UTC_EmptyUTC() throws Exception {
 128         ParsePosition pos = new ParsePosition(0);
 129         DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "").parseToBuilder("", pos);
 130         assertEquals(pos.getIndex(), 0);
 131         assertParsed(dtb, ZoneOffset.UTC);
 132     }
 133 
 134     public void test_parse_startStringMatch_UTC_EmptyUTC() throws Exception {
 135         ParsePosition pos = new ParsePosition(0);
 136         DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "").parseToBuilder("OTHER", pos);
 137         assertEquals(pos.getIndex(), 0);
 138         assertParsed(dtb, ZoneOffset.UTC);
 139     }
 140 
 141     public void test_parse_midStringMatch_UTC_EmptyUTC() throws Exception {
 142         ParsePosition pos = new ParsePosition(5);
 143         DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "").parseToBuilder("OTHEROTHER", pos);
 144         assertEquals(pos.getIndex(), 5);
 145         assertParsed(dtb, ZoneOffset.UTC);
 146     }
 147 
 148     public void test_parse_endStringMatch_UTC_EmptyUTC() throws Exception {
 149         ParsePosition pos = new ParsePosition(5);
 150         DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "").parseToBuilder("OTHER", pos);
 151         assertEquals(pos.getIndex(), 5);
 152         assertParsed(dtb, ZoneOffset.UTC);
 153     }
 154 
 155     //-----------------------------------------------------------------------
 156     @DataProvider(name="offsets")
 157     Object[][] provider_offsets() {
 158         return new Object[][] {
 159             {"+HH", "+00", ZoneOffset.UTC},
 160             {"+HH", "-00", ZoneOffset.UTC},
 161             {"+HH", "+01", ZoneOffset.ofHours(1)},
 162             {"+HH", "-01", ZoneOffset.ofHours(-1)},
 163 
 164             {"+HHMM", "+0000", ZoneOffset.UTC},
 165             {"+HHMM", "-0000", ZoneOffset.UTC},
 166             {"+HHMM", "+0102", ZoneOffset.ofHoursMinutes(1, 2)},
 167             {"+HHMM", "-0102", ZoneOffset.ofHoursMinutes(-1, -2)},
 168 
 169             {"+HH:MM", "+00:00", ZoneOffset.UTC},
 170             {"+HH:MM", "-00:00", ZoneOffset.UTC},
 171             {"+HH:MM", "+01:02", ZoneOffset.ofHoursMinutes(1, 2)},
 172             {"+HH:MM", "-01:02", ZoneOffset.ofHoursMinutes(-1, -2)},


 214             {"+HH:MM:ss", "+18:00:00", ZoneOffset.ofHoursMinutesSeconds(18, 0, 0)},
 215             {"+HH:MM:ss", "-01:00:00", ZoneOffset.ofHoursMinutesSeconds(-1, 0, 0)},
 216             {"+HH:MM:ss", "-02:00:00", ZoneOffset.ofHoursMinutesSeconds(-2, 0, 0)},
 217             {"+HH:MM:ss", "-18:00:00", ZoneOffset.ofHoursMinutesSeconds(-18, 0, 0)},
 218 
 219             {"+HHMMSS", "+000000", ZoneOffset.UTC},
 220             {"+HHMMSS", "-000000", ZoneOffset.UTC},
 221             {"+HHMMSS", "+010203", ZoneOffset.ofHoursMinutesSeconds(1, 2, 3)},
 222             {"+HHMMSS", "-010203", ZoneOffset.ofHoursMinutesSeconds(-1, -2, -3)},
 223 
 224             {"+HH:MM:SS", "+00:00:00", ZoneOffset.UTC},
 225             {"+HH:MM:SS", "-00:00:00", ZoneOffset.UTC},
 226             {"+HH:MM:SS", "+01:02:03", ZoneOffset.ofHoursMinutesSeconds(1, 2, 3)},
 227             {"+HH:MM:SS", "-01:02:03", ZoneOffset.ofHoursMinutesSeconds(-1, -2, -3)},
 228         };
 229     }
 230 
 231     @Test(dataProvider="offsets")
 232     public void test_parse_exactMatch(String pattern, String parse, ZoneOffset expected) throws Exception {
 233         ParsePosition pos = new ParsePosition(0);
 234         DateTimeBuilder dtb = getFormatter(pattern, "Z").parseToBuilder(parse, pos);
 235         assertEquals(pos.getIndex(), parse.length());
 236         assertParsed(dtb, expected);
 237     }
 238 
 239     @Test(dataProvider="offsets")
 240     public void test_parse_startStringMatch(String pattern, String parse, ZoneOffset expected) throws Exception {
 241         ParsePosition pos = new ParsePosition(0);
 242         DateTimeBuilder dtb = getFormatter(pattern, "Z").parseToBuilder(parse + ":OTHER", pos);
 243         assertEquals(pos.getIndex(), parse.length());
 244         assertParsed(dtb, expected);
 245     }
 246 
 247     @Test(dataProvider="offsets")
 248     public void test_parse_midStringMatch(String pattern, String parse, ZoneOffset expected) throws Exception {
 249         ParsePosition pos = new ParsePosition(5);
 250         DateTimeBuilder dtb = getFormatter(pattern, "Z").parseToBuilder("OTHER" + parse + ":OTHER", pos);
 251         assertEquals(pos.getIndex(), parse.length() + 5);
 252         assertParsed(dtb, expected);
 253     }
 254 
 255     @Test(dataProvider="offsets")
 256     public void test_parse_endStringMatch(String pattern, String parse, ZoneOffset expected) throws Exception {
 257         ParsePosition pos = new ParsePosition(5);
 258         DateTimeBuilder dtb = getFormatter(pattern, "Z").parseToBuilder("OTHER" + parse, pos);
 259         assertEquals(pos.getIndex(), parse.length() + 5);
 260         assertParsed(dtb, expected);
 261     }
 262 
 263     @Test(dataProvider="offsets")
 264     public void test_parse_exactMatch_EmptyUTC(String pattern, String parse, ZoneOffset expected) throws Exception {
 265         ParsePosition pos = new ParsePosition(0);
 266         DateTimeBuilder dtb = getFormatter(pattern, "").parseToBuilder(parse, pos);
 267         assertEquals(pos.getIndex(), parse.length());
 268         assertParsed(dtb, expected);
 269     }
 270 
 271     @Test(dataProvider="offsets")
 272     public void test_parse_startStringMatch_EmptyUTC(String pattern, String parse, ZoneOffset expected) throws Exception {
 273         ParsePosition pos = new ParsePosition(0);
 274         DateTimeBuilder dtb = getFormatter(pattern, "").parseToBuilder(parse + ":OTHER", pos);
 275         assertEquals(pos.getIndex(), parse.length());
 276         assertParsed(dtb, expected);
 277     }
 278 
 279     @Test(dataProvider="offsets")
 280     public void test_parse_midStringMatch_EmptyUTC(String pattern, String parse, ZoneOffset expected) throws Exception {
 281         ParsePosition pos = new ParsePosition(5);
 282         DateTimeBuilder dtb = getFormatter(pattern, "").parseToBuilder("OTHER" + parse + ":OTHER", pos);
 283         assertEquals(pos.getIndex(), parse.length() + 5);
 284         assertParsed(dtb, expected);
 285     }
 286 
 287     @Test(dataProvider="offsets")
 288     public void test_parse_endStringMatch_EmptyUTC(String pattern, String parse, ZoneOffset expected) throws Exception {
 289         ParsePosition pos = new ParsePosition(5);
 290         DateTimeBuilder dtb = getFormatter(pattern, "").parseToBuilder("OTHER" + parse, pos);
 291         assertEquals(pos.getIndex(), parse.length() + 5);
 292         assertParsed(dtb, expected);
 293     }
 294 
 295     //-----------------------------------------------------------------------
 296     @DataProvider(name="bigOffsets")
 297     Object[][] provider_bigOffsets() {
 298         return new Object[][] {
 299             {"+HH", "+59", 59 * 3600},
 300             {"+HH", "-19", -(19 * 3600)},
 301 
 302             {"+HHMM", "+1801", 18 * 3600 + 1 * 60},
 303             {"+HHMM", "-1801", -(18 * 3600 + 1 * 60)},
 304 
 305             {"+HH:MM", "+18:01", 18 * 3600 + 1 * 60},
 306             {"+HH:MM", "-18:01", -(18 * 3600 + 1 * 60)},
 307 
 308             {"+HHMMss", "+180103", 18 * 3600 + 1 * 60 + 3},
 309             {"+HHMMss", "-180103", -(18 * 3600 + 1 * 60 + 3)},
 310 
 311             {"+HH:MM:ss", "+18:01:03", 18 * 3600 + 1 * 60 + 3},
 312             {"+HH:MM:ss", "-18:01:03", -(18 * 3600 + 1 * 60 + 3)},
 313 
 314             {"+HHMMSS", "+180103", 18 * 3600 + 1 * 60 + 3},
 315             {"+HHMMSS", "-180103", -(18 * 3600 + 1 * 60 + 3)},
 316 
 317             {"+HH:MM:SS", "+18:01:03", 18 * 3600 + 1 * 60 + 3},
 318             {"+HH:MM:SS", "-18:01:03", -(18 * 3600 + 1 * 60 + 3)},
 319         };
 320     }
 321 
 322     @Test(dataProvider="bigOffsets")
 323     public void test_parse_bigOffsets(String pattern, String parse, long offsetSecs) throws Exception {
 324         ParsePosition pos = new ParsePosition(0);
 325         DateTimeBuilder dtb = getFormatter(pattern, "").parseToBuilder(parse, pos);
 326         assertEquals(pos.getIndex(), parse.length());
 327         assertEquals(dtb.getLong(OFFSET_SECONDS), offsetSecs);
 328     }
 329 
 330     //-----------------------------------------------------------------------
 331     @DataProvider(name="badOffsets")
 332     Object[][] provider_badOffsets() {
 333         return new Object[][] {
 334             {"+HH", "+1", 0},
 335             {"+HH", "-1", 0},
 336             {"+HH", "01", 0},
 337             {"+HH", "01", 0},
 338             {"+HH", "+AA", 0},
 339 
 340             {"+HHMM", "+1", 0},
 341             {"+HHMM", "+01", 0},
 342             {"+HHMM", "+001", 0},
 343             {"+HHMM", "0102", 0},
 344             {"+HHMM", "+01:02", 0},
 345             {"+HHMM", "+AAAA", 0},
 346 
 347             {"+HH:MM", "+1", 0},


 376             {"+HHMMSS", "+001", 0},
 377             {"+HHMMSS", "0102", 0},
 378             {"+HHMMSS", "+01:02", 0},
 379             {"+HHMMSS", "+AAAA", 0},
 380 
 381             {"+HH:MM:SS", "+1", 0},
 382             {"+HH:MM:SS", "+01", 0},
 383             {"+HH:MM:SS", "+0:01", 0},
 384             {"+HH:MM:SS", "+00:1", 0},
 385             {"+HH:MM:SS", "+0:1", 0},
 386             {"+HH:MM:SS", "+:", 0},
 387             {"+HH:MM:SS", "01:02", 0},
 388             {"+HH:MM:SS", "+0102", 0},
 389             {"+HH:MM:SS", "+AA:AA", 0},
 390         };
 391     }
 392 
 393     @Test(dataProvider="badOffsets")
 394     public void test_parse_invalid(String pattern, String parse, int expectedPosition) throws Exception {
 395         ParsePosition pos = new ParsePosition(0);
 396         DateTimeBuilder dtb = getFormatter(pattern, "Z").parseToBuilder(parse, pos);
 397         assertEquals(pos.getErrorIndex(), expectedPosition);

 398     }
 399 
 400     //-----------------------------------------------------------------------
 401     //-----------------------------------------------------------------------
 402     //-----------------------------------------------------------------------
 403     public void test_parse_caseSensitiveUTC_matchedCase() throws Exception {
 404         setCaseSensitive(true);
 405         ParsePosition pos = new ParsePosition(0);
 406         DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("Z", pos);
 407         assertEquals(pos.getIndex(), 1);
 408         assertParsed(dtb, ZoneOffset.UTC);
 409     }
 410 
 411     public void test_parse_caseSensitiveUTC_unmatchedCase() throws Exception {
 412         setCaseSensitive(true);
 413         ParsePosition pos = new ParsePosition(0);
 414         DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("z", pos);
 415         assertEquals(pos.getErrorIndex(), 0);
 416         assertEquals(dtb, null);
 417     }
 418 
 419     public void test_parse_caseInsensitiveUTC_matchedCase() throws Exception {
 420         setCaseSensitive(false);
 421         ParsePosition pos = new ParsePosition(0);
 422         DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("Z", pos);
 423         assertEquals(pos.getIndex(), 1);
 424         assertParsed(dtb, ZoneOffset.UTC);
 425     }
 426 
 427     public void test_parse_caseInsensitiveUTC_unmatchedCase() throws Exception {
 428         setCaseSensitive(false);
 429         ParsePosition pos = new ParsePosition(0);
 430         DateTimeBuilder dtb = getFormatter("+HH:MM:ss", "Z").parseToBuilder("z", pos);
 431         assertEquals(pos.getIndex(), 1);
 432         assertParsed(dtb, ZoneOffset.UTC);
 433     }
 434 
 435     private void assertParsed(DateTimeBuilder dtb, ZoneOffset expectedOffset) {
 436         if (expectedOffset == null) {
 437             assertEquals(dtb, null);
 438         } else {
 439             assertEquals(dtb.getFieldValueMap().size(), 1);
 440             assertEquals(dtb.getLong(OFFSET_SECONDS), (long) expectedOffset.getTotalSeconds());
 441         }
 442     }
 443 
 444 }


  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 test.java.time.format;
  61 
  62 import static java.time.temporal.ChronoField.OFFSET_SECONDS;
  63 import static org.testng.Assert.assertEquals;
  64 import static org.testng.Assert.assertTrue;
  65 
  66 import java.text.ParsePosition;
  67 import java.time.ZoneOffset;
  68 import java.time.temporal.TemporalAccessor;
  69 
  70 import org.testng.annotations.DataProvider;
  71 import org.testng.annotations.Test;
  72 
  73 /**
  74  * Test ZoneOffsetPrinterParser.
  75  */
  76 @Test(groups={"implementation"})
  77 public class TestZoneOffsetParser extends AbstractTestPrinterParser {
  78 
  79     //-----------------------------------------------------------------------
  80     @DataProvider(name="error")
  81     Object[][] data_error() {
  82         return new Object[][] {
  83             {"+HH:MM:ss", "Z", "hello", -1, IndexOutOfBoundsException.class},
  84             {"+HH:MM:ss", "Z", "hello", 6, IndexOutOfBoundsException.class},
  85         };
  86     }
  87 
  88     @Test(dataProvider="error")
  89     public void test_parse_error(String pattern, String noOffsetText, String text, int pos, Class<?> expected) {
  90         try {
  91             getFormatter(pattern, noOffsetText).parseUnresolved(text, new ParsePosition(pos));
  92         } catch (RuntimeException ex) {
  93             assertTrue(expected.isInstance(ex));
  94         }
  95     }
  96 
  97     //-----------------------------------------------------------------------
  98     public void test_parse_exactMatch_UTC() throws Exception {
  99         ParsePosition pos = new ParsePosition(0);
 100         TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("Z", pos);
 101         assertEquals(pos.getIndex(), 1);
 102         assertParsed(parsed, ZoneOffset.UTC);
 103     }
 104 
 105     public void test_parse_startStringMatch_UTC() throws Exception {
 106         ParsePosition pos = new ParsePosition(0);
 107         TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("ZOTHER", pos);
 108         assertEquals(pos.getIndex(), 1);
 109         assertParsed(parsed, ZoneOffset.UTC);
 110     }
 111 
 112     public void test_parse_midStringMatch_UTC() throws Exception {
 113         ParsePosition pos = new ParsePosition(5);
 114         TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("OTHERZOTHER", pos);
 115         assertEquals(pos.getIndex(), 6);
 116         assertParsed(parsed, ZoneOffset.UTC);
 117     }
 118 
 119     public void test_parse_endStringMatch_UTC() throws Exception {
 120         ParsePosition pos = new ParsePosition(5);
 121         TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("OTHERZ", pos);
 122         assertEquals(pos.getIndex(), 6);
 123         assertParsed(parsed, ZoneOffset.UTC);
 124     }
 125 
 126     //-----------------------------------------------------------------------
 127     public void test_parse_exactMatch_UTC_EmptyUTC() throws Exception {
 128         ParsePosition pos = new ParsePosition(0);
 129         TemporalAccessor parsed = getFormatter("+HH:MM:ss", "").parseUnresolved("", pos);
 130         assertEquals(pos.getIndex(), 0);
 131         assertParsed(parsed, ZoneOffset.UTC);
 132     }
 133 
 134     public void test_parse_startStringMatch_UTC_EmptyUTC() throws Exception {
 135         ParsePosition pos = new ParsePosition(0);
 136         TemporalAccessor parsed = getFormatter("+HH:MM:ss", "").parseUnresolved("OTHER", pos);
 137         assertEquals(pos.getIndex(), 0);
 138         assertParsed(parsed, ZoneOffset.UTC);
 139     }
 140 
 141     public void test_parse_midStringMatch_UTC_EmptyUTC() throws Exception {
 142         ParsePosition pos = new ParsePosition(5);
 143         TemporalAccessor parsed = getFormatter("+HH:MM:ss", "").parseUnresolved("OTHEROTHER", pos);
 144         assertEquals(pos.getIndex(), 5);
 145         assertParsed(parsed, ZoneOffset.UTC);
 146     }
 147 
 148     public void test_parse_endStringMatch_UTC_EmptyUTC() throws Exception {
 149         ParsePosition pos = new ParsePosition(5);
 150         TemporalAccessor parsed = getFormatter("+HH:MM:ss", "").parseUnresolved("OTHER", pos);
 151         assertEquals(pos.getIndex(), 5);
 152         assertParsed(parsed, ZoneOffset.UTC);
 153     }
 154 
 155     //-----------------------------------------------------------------------
 156     @DataProvider(name="offsets")
 157     Object[][] provider_offsets() {
 158         return new Object[][] {
 159             {"+HH", "+00", ZoneOffset.UTC},
 160             {"+HH", "-00", ZoneOffset.UTC},
 161             {"+HH", "+01", ZoneOffset.ofHours(1)},
 162             {"+HH", "-01", ZoneOffset.ofHours(-1)},
 163 
 164             {"+HHMM", "+0000", ZoneOffset.UTC},
 165             {"+HHMM", "-0000", ZoneOffset.UTC},
 166             {"+HHMM", "+0102", ZoneOffset.ofHoursMinutes(1, 2)},
 167             {"+HHMM", "-0102", ZoneOffset.ofHoursMinutes(-1, -2)},
 168 
 169             {"+HH:MM", "+00:00", ZoneOffset.UTC},
 170             {"+HH:MM", "-00:00", ZoneOffset.UTC},
 171             {"+HH:MM", "+01:02", ZoneOffset.ofHoursMinutes(1, 2)},
 172             {"+HH:MM", "-01:02", ZoneOffset.ofHoursMinutes(-1, -2)},


 214             {"+HH:MM:ss", "+18:00:00", ZoneOffset.ofHoursMinutesSeconds(18, 0, 0)},
 215             {"+HH:MM:ss", "-01:00:00", ZoneOffset.ofHoursMinutesSeconds(-1, 0, 0)},
 216             {"+HH:MM:ss", "-02:00:00", ZoneOffset.ofHoursMinutesSeconds(-2, 0, 0)},
 217             {"+HH:MM:ss", "-18:00:00", ZoneOffset.ofHoursMinutesSeconds(-18, 0, 0)},
 218 
 219             {"+HHMMSS", "+000000", ZoneOffset.UTC},
 220             {"+HHMMSS", "-000000", ZoneOffset.UTC},
 221             {"+HHMMSS", "+010203", ZoneOffset.ofHoursMinutesSeconds(1, 2, 3)},
 222             {"+HHMMSS", "-010203", ZoneOffset.ofHoursMinutesSeconds(-1, -2, -3)},
 223 
 224             {"+HH:MM:SS", "+00:00:00", ZoneOffset.UTC},
 225             {"+HH:MM:SS", "-00:00:00", ZoneOffset.UTC},
 226             {"+HH:MM:SS", "+01:02:03", ZoneOffset.ofHoursMinutesSeconds(1, 2, 3)},
 227             {"+HH:MM:SS", "-01:02:03", ZoneOffset.ofHoursMinutesSeconds(-1, -2, -3)},
 228         };
 229     }
 230 
 231     @Test(dataProvider="offsets")
 232     public void test_parse_exactMatch(String pattern, String parse, ZoneOffset expected) throws Exception {
 233         ParsePosition pos = new ParsePosition(0);
 234         TemporalAccessor parsed = getFormatter(pattern, "Z").parseUnresolved(parse, pos);
 235         assertEquals(pos.getIndex(), parse.length());
 236         assertParsed(parsed, expected);
 237     }
 238 
 239     @Test(dataProvider="offsets")
 240     public void test_parse_startStringMatch(String pattern, String parse, ZoneOffset expected) throws Exception {
 241         ParsePosition pos = new ParsePosition(0);
 242         TemporalAccessor parsed = getFormatter(pattern, "Z").parseUnresolved(parse + ":OTHER", pos);
 243         assertEquals(pos.getIndex(), parse.length());
 244         assertParsed(parsed, expected);
 245     }
 246 
 247     @Test(dataProvider="offsets")
 248     public void test_parse_midStringMatch(String pattern, String parse, ZoneOffset expected) throws Exception {
 249         ParsePosition pos = new ParsePosition(5);
 250         TemporalAccessor parsed = getFormatter(pattern, "Z").parseUnresolved("OTHER" + parse + ":OTHER", pos);
 251         assertEquals(pos.getIndex(), parse.length() + 5);
 252         assertParsed(parsed, expected);
 253     }
 254 
 255     @Test(dataProvider="offsets")
 256     public void test_parse_endStringMatch(String pattern, String parse, ZoneOffset expected) throws Exception {
 257         ParsePosition pos = new ParsePosition(5);
 258         TemporalAccessor parsed = getFormatter(pattern, "Z").parseUnresolved("OTHER" + parse, pos);
 259         assertEquals(pos.getIndex(), parse.length() + 5);
 260         assertParsed(parsed, expected);
 261     }
 262 
 263     @Test(dataProvider="offsets")
 264     public void test_parse_exactMatch_EmptyUTC(String pattern, String parse, ZoneOffset expected) throws Exception {
 265         ParsePosition pos = new ParsePosition(0);
 266         TemporalAccessor parsed = getFormatter(pattern, "").parseUnresolved(parse, pos);
 267         assertEquals(pos.getIndex(), parse.length());
 268         assertParsed(parsed, expected);
 269     }
 270 
 271     @Test(dataProvider="offsets")
 272     public void test_parse_startStringMatch_EmptyUTC(String pattern, String parse, ZoneOffset expected) throws Exception {
 273         ParsePosition pos = new ParsePosition(0);
 274         TemporalAccessor parsed = getFormatter(pattern, "").parseUnresolved(parse + ":OTHER", pos);
 275         assertEquals(pos.getIndex(), parse.length());
 276         assertParsed(parsed, expected);
 277     }
 278 
 279     @Test(dataProvider="offsets")
 280     public void test_parse_midStringMatch_EmptyUTC(String pattern, String parse, ZoneOffset expected) throws Exception {
 281         ParsePosition pos = new ParsePosition(5);
 282         TemporalAccessor parsed = getFormatter(pattern, "").parseUnresolved("OTHER" + parse + ":OTHER", pos);
 283         assertEquals(pos.getIndex(), parse.length() + 5);
 284         assertParsed(parsed, expected);
 285     }
 286 
 287     @Test(dataProvider="offsets")
 288     public void test_parse_endStringMatch_EmptyUTC(String pattern, String parse, ZoneOffset expected) throws Exception {
 289         ParsePosition pos = new ParsePosition(5);
 290         TemporalAccessor parsed = getFormatter(pattern, "").parseUnresolved("OTHER" + parse, pos);
 291         assertEquals(pos.getIndex(), parse.length() + 5);
 292         assertParsed(parsed, expected);
 293     }
 294 
 295     //-----------------------------------------------------------------------
 296     @DataProvider(name="bigOffsets")
 297     Object[][] provider_bigOffsets() {
 298         return new Object[][] {
 299             {"+HH", "+59", 59 * 3600},
 300             {"+HH", "-19", -(19 * 3600)},
 301 
 302             {"+HHMM", "+1801", 18 * 3600 + 1 * 60},
 303             {"+HHMM", "-1801", -(18 * 3600 + 1 * 60)},
 304 
 305             {"+HH:MM", "+18:01", 18 * 3600 + 1 * 60},
 306             {"+HH:MM", "-18:01", -(18 * 3600 + 1 * 60)},
 307 
 308             {"+HHMMss", "+180103", 18 * 3600 + 1 * 60 + 3},
 309             {"+HHMMss", "-180103", -(18 * 3600 + 1 * 60 + 3)},
 310 
 311             {"+HH:MM:ss", "+18:01:03", 18 * 3600 + 1 * 60 + 3},
 312             {"+HH:MM:ss", "-18:01:03", -(18 * 3600 + 1 * 60 + 3)},
 313 
 314             {"+HHMMSS", "+180103", 18 * 3600 + 1 * 60 + 3},
 315             {"+HHMMSS", "-180103", -(18 * 3600 + 1 * 60 + 3)},
 316 
 317             {"+HH:MM:SS", "+18:01:03", 18 * 3600 + 1 * 60 + 3},
 318             {"+HH:MM:SS", "-18:01:03", -(18 * 3600 + 1 * 60 + 3)},
 319         };
 320     }
 321 
 322     @Test(dataProvider="bigOffsets")
 323     public void test_parse_bigOffsets(String pattern, String parse, long offsetSecs) throws Exception {
 324         ParsePosition pos = new ParsePosition(0);
 325         TemporalAccessor parsed = getFormatter(pattern, "").parseUnresolved(parse, pos);
 326         assertEquals(pos.getIndex(), parse.length());
 327         assertEquals(parsed.getLong(OFFSET_SECONDS), offsetSecs);
 328     }
 329 
 330     //-----------------------------------------------------------------------
 331     @DataProvider(name="badOffsets")
 332     Object[][] provider_badOffsets() {
 333         return new Object[][] {
 334             {"+HH", "+1", 0},
 335             {"+HH", "-1", 0},
 336             {"+HH", "01", 0},
 337             {"+HH", "01", 0},
 338             {"+HH", "+AA", 0},
 339 
 340             {"+HHMM", "+1", 0},
 341             {"+HHMM", "+01", 0},
 342             {"+HHMM", "+001", 0},
 343             {"+HHMM", "0102", 0},
 344             {"+HHMM", "+01:02", 0},
 345             {"+HHMM", "+AAAA", 0},
 346 
 347             {"+HH:MM", "+1", 0},


 376             {"+HHMMSS", "+001", 0},
 377             {"+HHMMSS", "0102", 0},
 378             {"+HHMMSS", "+01:02", 0},
 379             {"+HHMMSS", "+AAAA", 0},
 380 
 381             {"+HH:MM:SS", "+1", 0},
 382             {"+HH:MM:SS", "+01", 0},
 383             {"+HH:MM:SS", "+0:01", 0},
 384             {"+HH:MM:SS", "+00:1", 0},
 385             {"+HH:MM:SS", "+0:1", 0},
 386             {"+HH:MM:SS", "+:", 0},
 387             {"+HH:MM:SS", "01:02", 0},
 388             {"+HH:MM:SS", "+0102", 0},
 389             {"+HH:MM:SS", "+AA:AA", 0},
 390         };
 391     }
 392 
 393     @Test(dataProvider="badOffsets")
 394     public void test_parse_invalid(String pattern, String parse, int expectedPosition) throws Exception {
 395         ParsePosition pos = new ParsePosition(0);
 396         TemporalAccessor parsed = getFormatter(pattern, "Z").parseUnresolved(parse, pos);
 397         assertEquals(pos.getErrorIndex(), expectedPosition);
 398         assertEquals(parsed, null);
 399     }
 400 
 401     //-----------------------------------------------------------------------
 402     //-----------------------------------------------------------------------
 403     //-----------------------------------------------------------------------
 404     public void test_parse_caseSensitiveUTC_matchedCase() throws Exception {
 405         setCaseSensitive(true);
 406         ParsePosition pos = new ParsePosition(0);
 407         TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("Z", pos);
 408         assertEquals(pos.getIndex(), 1);
 409         assertParsed(parsed, ZoneOffset.UTC);
 410     }
 411 
 412     public void test_parse_caseSensitiveUTC_unmatchedCase() throws Exception {
 413         setCaseSensitive(true);
 414         ParsePosition pos = new ParsePosition(0);
 415         TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("z", pos);
 416         assertEquals(pos.getErrorIndex(), 0);
 417         assertEquals(parsed, null);
 418     }
 419 
 420     public void test_parse_caseInsensitiveUTC_matchedCase() throws Exception {
 421         setCaseSensitive(false);
 422         ParsePosition pos = new ParsePosition(0);
 423         TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("Z", pos);
 424         assertEquals(pos.getIndex(), 1);
 425         assertParsed(parsed, ZoneOffset.UTC);
 426     }
 427 
 428     public void test_parse_caseInsensitiveUTC_unmatchedCase() throws Exception {
 429         setCaseSensitive(false);
 430         ParsePosition pos = new ParsePosition(0);
 431         TemporalAccessor parsed = getFormatter("+HH:MM:ss", "Z").parseUnresolved("z", pos);
 432         assertEquals(pos.getIndex(), 1);
 433         assertParsed(parsed, ZoneOffset.UTC);
 434     }
 435 
 436     private void assertParsed(TemporalAccessor parsed, ZoneOffset expectedOffset) {
 437         if (expectedOffset == null) {
 438             assertEquals(parsed, null);
 439         } else {
 440             assertEquals(parsed.isSupported(OFFSET_SECONDS), true);
 441             assertEquals(parsed.getLong(OFFSET_SECONDS), (long) expectedOffset.getTotalSeconds());
 442         }
 443     }
 444 
 445 }