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; 61 62 import static org.testng.Assert.assertEquals; 63 import static org.testng.Assert.fail; 64 65 import java.io.ByteArrayInputStream; 66 import java.io.ByteArrayOutputStream; 67 import java.io.DataInputStream; 68 import java.io.DataOutputStream; 69 import java.io.IOException; 70 import java.io.ObjectInputStream; 71 import java.io.ObjectStreamConstants; 72 import java.lang.reflect.Field; 73 import java.time.DateTimeException; 74 import java.time.LocalTime; 75 import java.time.ZoneId; 76 import java.time.ZoneOffset; 77 import java.time.temporal.Queries; 78 import java.time.temporal.TemporalAccessor; 79 import java.time.temporal.TemporalField; 80 import java.time.temporal.TemporalQuery; 81 import java.time.zone.ZoneRulesException; 82 import java.util.HashMap; 83 import java.util.Map; 84 85 import org.testng.annotations.DataProvider; 86 import org.testng.annotations.Test; 87 88 /** 89 * Test ZoneId. 90 */ 91 @Test 92 public class TCKZoneId extends AbstractTCKTest { 93 94 //----------------------------------------------------------------------- 95 @Test 96 public void test_serialization() throws Exception { 97 assertSerializable(ZoneId.of("Europe/London")); 98 assertSerializable(ZoneId.of("America/Chicago")); 99 } 100 101 @Test 102 public void test_serialization_format() throws Exception { 103 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 104 try (DataOutputStream dos = new DataOutputStream(baos) ) { 105 dos.writeByte(7); 106 dos.writeUTF("Europe/London"); 107 } 108 byte[] bytes = baos.toByteArray(); 109 assertSerializedBySer(ZoneId.of("Europe/London"), bytes); 110 } 111 112 @Test 113 public void test_deserialization_lenient_characters() throws Exception { 114 // an ID can be loaded without validation during deserialization 115 String id = "QWERTYUIOPASDFGHJKLZXCVBNM~/._+-"; 116 ZoneId deser = deserialize(id); 117 // getting the ID and string are OK 118 assertEquals(deser.getId(), id); 119 assertEquals(deser.toString(), id); 120 // getting the rules is not 121 try { 122 deser.getRules(); 123 fail(); 124 } catch (ZoneRulesException ex) { 125 // expected 126 } 127 } 128 129 @Test(expectedExceptions=DateTimeException.class) 130 public void test_deserialization_lenient_badCharacters() throws Exception { 131 // an ID can be loaded without validation during deserialization 132 // but there is a check to ensure the ID format is valid 133 deserialize("|!?"); 134 } 135 136 @Test(dataProvider="offsetBasedValid", expectedExceptions=DateTimeException.class) 137 public void test_deserialization_lenient_offsetNotAllowed_noPrefix(String input, String resolvedId) throws Exception { 138 // an ID can be loaded without validation during deserialization 139 // but there is a check to ensure the ID format is valid 140 deserialize(input); 141 } 142 143 @Test(dataProvider="offsetBasedValid", expectedExceptions=DateTimeException.class) 144 public void test_deserialization_lenient_offsetNotAllowed_prefixUTC(String input, String resolvedId) throws Exception { 145 // an ID can be loaded without validation during deserialization 146 // but there is a check to ensure the ID format is valid 147 deserialize("UTC" + input); 148 } 149 150 @Test(dataProvider="offsetBasedValid", expectedExceptions=DateTimeException.class) 151 public void test_deserialization_lenient_offsetNotAllowed_prefixGMT(String input, String resolvedId) throws Exception { 152 // an ID can be loaded without validation during deserialization 153 // but there is a check to ensure the ID format is valid 154 deserialize("GMT" + input); 155 } 156 157 @Test(dataProvider="offsetBasedValid", expectedExceptions=DateTimeException.class) 158 public void test_deserialization_lenient_offsetNotAllowed_prefixUT(String input, String resolvedId) throws Exception { 159 // an ID can be loaded without validation during deserialization 160 // but there is a check to ensure the ID format is valid 161 deserialize("UT" + input); 162 } 163 164 private ZoneId deserialize(String id) throws Exception { 165 String serClass = ZoneId.class.getPackage().getName() + ".Ser"; 166 Class<?> serCls = Class.forName(serClass); 167 Field field = serCls.getDeclaredField("serialVersionUID"); 168 field.setAccessible(true); 169 long serVer = (Long) field.get(null); 170 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 171 try (DataOutputStream dos = new DataOutputStream(baos)) { 172 dos.writeShort(ObjectStreamConstants.STREAM_MAGIC); 173 dos.writeShort(ObjectStreamConstants.STREAM_VERSION); 174 dos.writeByte(ObjectStreamConstants.TC_OBJECT); 175 dos.writeByte(ObjectStreamConstants.TC_CLASSDESC); 176 dos.writeUTF(serClass); 177 dos.writeLong(serVer); 178 dos.writeByte(ObjectStreamConstants.SC_EXTERNALIZABLE | ObjectStreamConstants.SC_BLOCK_DATA); 179 dos.writeShort(0); // number of fields 180 dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); // end of classdesc 181 dos.writeByte(ObjectStreamConstants.TC_NULL); // no superclasses 182 dos.writeByte(ObjectStreamConstants.TC_BLOCKDATA); 183 dos.writeByte(1 + 2 + id.length()); // length of data (1 byte + 2 bytes UTF length + 32 bytes UTF) 184 dos.writeByte(7); // ZoneId 185 dos.writeUTF(id); 186 dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); // end of blockdata 187 } 188 ZoneId deser = null; 189 try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) { 190 deser = (ZoneId) ois.readObject(); 191 } 192 return deser; 193 } 194 195 //----------------------------------------------------------------------- 196 // OLD_IDS_PRE_2005 197 //----------------------------------------------------------------------- 198 public void test_constant_OLD_IDS_PRE_2005() { 199 Map<String, String> ids = ZoneId.OLD_IDS_PRE_2005; 200 assertEquals(ids.get("EST"), "America/New_York"); 201 assertEquals(ids.get("MST"), "America/Denver"); 202 assertEquals(ids.get("HST"), "Pacific/Honolulu"); 203 assertEquals(ids.get("ACT"), "Australia/Darwin"); 204 assertEquals(ids.get("AET"), "Australia/Sydney"); 205 assertEquals(ids.get("AGT"), "America/Argentina/Buenos_Aires"); 206 assertEquals(ids.get("ART"), "Africa/Cairo"); 207 assertEquals(ids.get("AST"), "America/Anchorage"); 208 assertEquals(ids.get("BET"), "America/Sao_Paulo"); 209 assertEquals(ids.get("BST"), "Asia/Dhaka"); 210 assertEquals(ids.get("CAT"), "Africa/Harare"); 211 assertEquals(ids.get("CNT"), "America/St_Johns"); 212 assertEquals(ids.get("CST"), "America/Chicago"); 213 assertEquals(ids.get("CTT"), "Asia/Shanghai"); 214 assertEquals(ids.get("EAT"), "Africa/Addis_Ababa"); 215 assertEquals(ids.get("ECT"), "Europe/Paris"); 216 assertEquals(ids.get("IET"), "America/Indiana/Indianapolis"); 217 assertEquals(ids.get("IST"), "Asia/Kolkata"); 218 assertEquals(ids.get("JST"), "Asia/Tokyo"); 219 assertEquals(ids.get("MIT"), "Pacific/Apia"); 220 assertEquals(ids.get("NET"), "Asia/Yerevan"); 221 assertEquals(ids.get("NST"), "Pacific/Auckland"); 222 assertEquals(ids.get("PLT"), "Asia/Karachi"); 223 assertEquals(ids.get("PNT"), "America/Phoenix"); 224 assertEquals(ids.get("PRT"), "America/Puerto_Rico"); 225 assertEquals(ids.get("PST"), "America/Los_Angeles"); 226 assertEquals(ids.get("SST"), "Pacific/Guadalcanal"); 227 assertEquals(ids.get("VST"), "Asia/Ho_Chi_Minh"); 228 } 229 230 @Test(expectedExceptions=UnsupportedOperationException.class) 231 public void test_constant_OLD_IDS_PRE_2005_immutable() { 232 Map<String, String> ids = ZoneId.OLD_IDS_PRE_2005; 233 ids.clear(); 234 } 235 236 //----------------------------------------------------------------------- 237 // OLD_IDS_POST_2005 238 //----------------------------------------------------------------------- 239 public void test_constant_OLD_IDS_POST_2005() { 240 Map<String, String> ids = ZoneId.OLD_IDS_POST_2005; 241 assertEquals(ids.get("EST"), "-05:00"); 242 assertEquals(ids.get("MST"), "-07:00"); 243 assertEquals(ids.get("HST"), "-10:00"); 244 assertEquals(ids.get("ACT"), "Australia/Darwin"); 245 assertEquals(ids.get("AET"), "Australia/Sydney"); 246 assertEquals(ids.get("AGT"), "America/Argentina/Buenos_Aires"); 247 assertEquals(ids.get("ART"), "Africa/Cairo"); 248 assertEquals(ids.get("AST"), "America/Anchorage"); 249 assertEquals(ids.get("BET"), "America/Sao_Paulo"); 250 assertEquals(ids.get("BST"), "Asia/Dhaka"); 251 assertEquals(ids.get("CAT"), "Africa/Harare"); 252 assertEquals(ids.get("CNT"), "America/St_Johns"); 253 assertEquals(ids.get("CST"), "America/Chicago"); 254 assertEquals(ids.get("CTT"), "Asia/Shanghai"); 255 assertEquals(ids.get("EAT"), "Africa/Addis_Ababa"); 256 assertEquals(ids.get("ECT"), "Europe/Paris"); 257 assertEquals(ids.get("IET"), "America/Indiana/Indianapolis"); 258 assertEquals(ids.get("IST"), "Asia/Kolkata"); 259 assertEquals(ids.get("JST"), "Asia/Tokyo"); 260 assertEquals(ids.get("MIT"), "Pacific/Apia"); 261 assertEquals(ids.get("NET"), "Asia/Yerevan"); 262 assertEquals(ids.get("NST"), "Pacific/Auckland"); 263 assertEquals(ids.get("PLT"), "Asia/Karachi"); 264 assertEquals(ids.get("PNT"), "America/Phoenix"); 265 assertEquals(ids.get("PRT"), "America/Puerto_Rico"); 266 assertEquals(ids.get("PST"), "America/Los_Angeles"); 267 assertEquals(ids.get("SST"), "Pacific/Guadalcanal"); 268 assertEquals(ids.get("VST"), "Asia/Ho_Chi_Minh"); 269 } 270 271 @Test(expectedExceptions=UnsupportedOperationException.class) 272 public void test_constant_OLD_IDS_POST_2005_immutable() { 273 Map<String, String> ids = ZoneId.OLD_IDS_POST_2005; 274 ids.clear(); 275 } 276 277 //----------------------------------------------------------------------- 278 // mapped factory 279 //----------------------------------------------------------------------- 280 @Test 281 public void test_of_string_Map() { 282 Map<String, String> map = new HashMap<>(); 283 map.put("LONDON", "Europe/London"); 284 map.put("PARIS", "Europe/Paris"); 285 ZoneId test = ZoneId.of("LONDON", map); 286 assertEquals(test.getId(), "Europe/London"); 287 } 288 289 @Test 290 public void test_of_string_Map_lookThrough() { 291 Map<String, String> map = new HashMap<>(); 292 map.put("LONDON", "Europe/London"); 293 map.put("PARIS", "Europe/Paris"); 294 ZoneId test = ZoneId.of("Europe/Madrid", map); 295 assertEquals(test.getId(), "Europe/Madrid"); 296 } 297 298 @Test 299 public void test_of_string_Map_emptyMap() { 300 Map<String, String> map = new HashMap<>(); 301 ZoneId test = ZoneId.of("Europe/Madrid", map); 302 assertEquals(test.getId(), "Europe/Madrid"); 303 } 304 305 @Test(expectedExceptions=DateTimeException.class) 306 public void test_of_string_Map_badFormat() { 307 Map<String, String> map = new HashMap<>(); 308 ZoneId.of("Not known", map); 309 } 310 311 @Test(expectedExceptions=ZoneRulesException.class) 312 public void test_of_string_Map_unknown() { 313 Map<String, String> map = new HashMap<>(); 314 ZoneId.of("Unknown", map); 315 } 316 317 //----------------------------------------------------------------------- 318 // regular factory 319 //----------------------------------------------------------------------- 320 @DataProvider(name="offsetBasedZero") 321 Object[][] data_offsetBasedZero() { 322 return new Object[][] { 323 {""}, {"0"}, 324 {"+00"},{"+0000"},{"+00:00"},{"+000000"},{"+00:00:00"}, 325 {"-00"},{"-0000"},{"-00:00"},{"-000000"},{"-00:00:00"}, 326 }; 327 } 328 329 @Test(dataProvider="offsetBasedZero") 330 public void factory_of_String_offsetBasedZero_noPrefix(String id) { 331 if (id.length() > 0 && id.equals("0") == false) { 332 ZoneId test = ZoneId.of(id); 333 assertEquals(test, ZoneOffset.UTC); 334 } 335 } 336 337 @Test(dataProvider="offsetBasedZero") 338 public void factory_of_String_offsetBasedZero_prefixUTC(String id) { 339 ZoneId test = ZoneId.of("UTC" + id); 340 assertEquals(test, ZoneOffset.UTC); 341 } 342 343 @Test(dataProvider="offsetBasedZero") 344 public void factory_of_String_offsetBasedZero_prefixGMT(String id) { 345 ZoneId test = ZoneId.of("GMT" + id); 346 assertEquals(test, ZoneOffset.UTC); 347 } 348 349 @Test(dataProvider="offsetBasedZero") 350 public void factory_of_String_offsetBasedZero_prefixUT(String id) { 351 ZoneId test = ZoneId.of("UT" + id); 352 assertEquals(test, ZoneOffset.UTC); 353 } 354 355 @Test 356 public void factory_of_String_offsetBasedZero_z() { 357 ZoneId test = ZoneId.of("Z"); 358 assertEquals(test, ZoneOffset.UTC); 359 } 360 361 //----------------------------------------------------------------------- 362 @DataProvider(name="offsetBasedValid") 363 Object[][] data_offsetBasedValid() { 364 return new Object[][] { 365 {"+0", "Z"}, 366 {"+5", "+05:00"}, 367 {"+01", "+01:00"}, 368 {"+0100", "+01:00"},{"+01:00", "+01:00"}, 369 {"+010000", "+01:00"},{"+01:00:00", "+01:00"}, 370 {"+12", "+12:00"}, 371 {"+1234", "+12:34"},{"+12:34", "+12:34"}, 372 {"+123456", "+12:34:56"},{"+12:34:56", "+12:34:56"}, 373 {"-02", "-02:00"}, 374 {"-5", "-05:00"}, 375 {"-0200", "-02:00"},{"-02:00", "-02:00"}, 376 {"-020000", "-02:00"},{"-02:00:00", "-02:00"}, 377 }; 378 } 379 380 @Test(dataProvider="offsetBasedValid") 381 public void factory_of_String_offsetBasedValid_noPrefix(String input, String id) { 382 ZoneId test = ZoneId.of(input); 383 assertEquals(test.getId(), id); 384 assertEquals(test, ZoneOffset.of(id)); 385 } 386 387 @Test(dataProvider="offsetBasedValid") 388 public void factory_of_String_offsetBasedValid_prefixUTC(String input, String id) { 389 ZoneId test = ZoneId.of("UTC" + input); 390 assertEquals(test.getId(), id); 391 assertEquals(test, ZoneOffset.of(id)); 392 } 393 394 @Test(dataProvider="offsetBasedValid") 395 public void factory_of_String_offsetBasedValid_prefixGMT(String input, String id) { 396 ZoneId test = ZoneId.of("GMT" + input); 397 assertEquals(test.getId(), id); 398 assertEquals(test, ZoneOffset.of(id)); 399 } 400 401 @Test(dataProvider="offsetBasedValid") 402 public void factory_of_String_offsetBasedValid_prefixUT(String input, String id) { 403 ZoneId test = ZoneId.of("UT" + input); 404 assertEquals(test.getId(), id); 405 assertEquals(test, ZoneOffset.of(id)); 406 } 407 408 //----------------------------------------------------------------------- 409 @DataProvider(name="offsetBasedInvalid") 410 Object[][] data_offsetBasedInvalid() { 411 return new Object[][] { 412 {"A"}, {"B"}, {"C"}, {"D"}, {"E"}, {"F"}, {"G"}, {"H"}, {"I"}, {"J"}, {"K"}, {"L"}, {"M"}, 413 {"N"}, {"O"}, {"P"}, {"Q"}, {"R"}, {"S"}, {"T"}, {"U"}, {"V"}, {"W"}, {"X"}, {"Y"}, {"Z"}, 414 {"+0:00"}, {"+00:0"}, {"+0:0"}, 415 {"+000"}, {"+00000"}, 416 {"+0:00:00"}, {"+00:0:00"}, {"+00:00:0"}, {"+0:0:0"}, {"+0:0:00"}, {"+00:0:0"}, {"+0:00:0"}, 417 {"+01_00"}, {"+01;00"}, {"+01@00"}, {"+01:AA"}, 418 {"+19"}, {"+19:00"}, {"+18:01"}, {"+18:00:01"}, {"+1801"}, {"+180001"}, 419 {"-0:00"}, {"-00:0"}, {"-0:0"}, 420 {"-000"}, {"-00000"}, 421 {"-0:00:00"}, {"-00:0:00"}, {"-00:00:0"}, {"-0:0:0"}, {"-0:0:00"}, {"-00:0:0"}, {"-0:00:0"}, 422 {"-19"}, {"-19:00"}, {"-18:01"}, {"-18:00:01"}, {"-1801"}, {"-180001"}, 423 {"-01_00"}, {"-01;00"}, {"-01@00"}, {"-01:AA"}, 424 {"@01:00"}, 425 }; 426 } 427 428 @Test(dataProvider="offsetBasedInvalid", expectedExceptions=DateTimeException.class) 429 public void factory_of_String_offsetBasedInvalid_noPrefix(String id) { 430 if (id.equals("Z")) { 431 throw new DateTimeException("Fake exception: Z alone is valid, not invalid"); 432 } 433 ZoneId.of(id); 434 } 435 436 @Test(dataProvider="offsetBasedInvalid", expectedExceptions=DateTimeException.class) 437 public void factory_of_String_offsetBasedInvalid_prefixUTC(String id) { 438 ZoneId.of("UTC" + id); 439 } 440 441 @Test(dataProvider="offsetBasedInvalid", expectedExceptions=DateTimeException.class) 442 public void factory_of_String_offsetBasedInvalid_prefixGMT(String id) { 443 ZoneId.of("GMT" + id); 444 } 445 446 @Test(dataProvider="offsetBasedInvalid", expectedExceptions=DateTimeException.class) 447 public void factory_of_String_offsetBasedInvalid_prefixUT(String id) { 448 if (id.equals("C")) { 449 throw new DateTimeException("Fake exception: UT + C = UTC, thus it is valid, not invalid"); 450 } 451 ZoneId.of("UT" + id); 452 } 453 454 //----------------------------------------------------------------------- 455 @DataProvider(name="regionBasedInvalid") 456 Object[][] data_regionBasedInvalid() { 457 // \u00ef is a random unicode character 458 return new Object[][] { 459 {""}, {":"}, {"#"}, 460 {"\u00ef"}, {"`"}, {"!"}, {"\""}, {"\u00ef"}, {"$"}, {"^"}, {"&"}, {"*"}, {"("}, {")"}, {"="}, 461 {"\\"}, {"|"}, {","}, {"<"}, {">"}, {"?"}, {";"}, {"'"}, {"["}, {"]"}, {"{"}, {"}"}, 462 {"\u00ef:A"}, {"`:A"}, {"!:A"}, {"\":A"}, {"\u00ef:A"}, {"$:A"}, {"^:A"}, {"&:A"}, {"*:A"}, {"(:A"}, {"):A"}, {"=:A"}, {"+:A"}, 463 {"\\:A"}, {"|:A"}, {",:A"}, {"<:A"}, {">:A"}, {"?:A"}, {";:A"}, {"::A"}, {"':A"}, {"@:A"}, {"~:A"}, {"[:A"}, {"]:A"}, {"{:A"}, {"}:A"}, 464 {"A:B#\u00ef"}, {"A:B#`"}, {"A:B#!"}, {"A:B#\""}, {"A:B#\u00ef"}, {"A:B#$"}, {"A:B#^"}, {"A:B#&"}, {"A:B#*"}, 465 {"A:B#("}, {"A:B#)"}, {"A:B#="}, {"A:B#+"}, 466 {"A:B#\\"}, {"A:B#|"}, {"A:B#,"}, {"A:B#<"}, {"A:B#>"}, {"A:B#?"}, {"A:B#;"}, {"A:B#:"}, 467 {"A:B#'"}, {"A:B#@"}, {"A:B#~"}, {"A:B#["}, {"A:B#]"}, {"A:B#{"}, {"A:B#}"}, 468 }; 469 } 470 471 @Test(dataProvider="regionBasedInvalid", expectedExceptions=DateTimeException.class) 472 public void factory_of_String_regionBasedInvalid(String id) { 473 ZoneId.of(id); 474 } 475 476 //----------------------------------------------------------------------- 477 @Test 478 public void factory_of_String_region_EuropeLondon() { 479 ZoneId test = ZoneId.of("Europe/London"); 480 assertEquals(test.getId(), "Europe/London"); 481 assertEquals(test.getRules().isFixedOffset(), false); 482 } 483 484 //----------------------------------------------------------------------- 485 @Test(expectedExceptions=NullPointerException.class) 486 public void factory_of_String_null() { 487 ZoneId.of(null); 488 } 489 490 @Test(expectedExceptions=DateTimeException.class) 491 public void factory_of_String_badFormat() { 492 ZoneId.of("Unknown rule"); 493 } 494 495 @Test(expectedExceptions=ZoneRulesException.class) 496 public void factory_of_String_unknown() { 497 ZoneId.of("Unknown"); 498 } 499 500 //----------------------------------------------------------------------- 501 // from(TemporalAccessor) 502 //----------------------------------------------------------------------- 503 @Test 504 public void factory_from_TemporalAccessor_zoneId() { 505 TemporalAccessor mock = new TemporalAccessor() { 506 @Override 507 public boolean isSupported(TemporalField field) { 508 return false; 509 } 510 @Override 511 public long getLong(TemporalField field) { 512 throw new DateTimeException("Mock"); 513 } 514 @SuppressWarnings("unchecked") 515 @Override 516 public <R> R query(TemporalQuery<R> query) { 517 if (query == Queries.zoneId()) { 518 return (R) ZoneId.of("Europe/Paris"); 519 } 520 return TemporalAccessor.super.query(query); 521 } 522 }; 523 assertEquals(ZoneId.from(mock), ZoneId.of("Europe/Paris")); 524 } 525 526 @Test 527 public void factory_from_TemporalAccessor_offset() { 528 ZoneOffset offset = ZoneOffset.ofHours(1); 529 assertEquals(ZoneId.from(offset), offset); 530 } 531 532 @Test(expectedExceptions=DateTimeException.class) 533 public void factory_from_TemporalAccessor_invalid_noDerive() { 534 ZoneId.from(LocalTime.of(12, 30)); 535 } 536 537 @Test(expectedExceptions=NullPointerException.class) 561 562 @Test 563 public void test_equals_null() { 564 assertEquals(ZoneId.of("Europe/London").equals(null), false); 565 } 566 567 @Test 568 public void test_equals_notEqualWrongType() { 569 assertEquals(ZoneId.of("Europe/London").equals("Europe/London"), false); 570 } 571 572 //----------------------------------------------------------------------- 573 // toString() 574 //----------------------------------------------------------------------- 575 @DataProvider(name="toString") 576 Object[][] data_toString() { 577 return new Object[][] { 578 {"Europe/London", "Europe/London"}, 579 {"Europe/Paris", "Europe/Paris"}, 580 {"Europe/Berlin", "Europe/Berlin"}, 581 {"UTC", "Z"}, 582 {"UTC+01:00", "+01:00"}, 583 }; 584 } 585 586 @Test(dataProvider="toString") 587 public void test_toString(String id, String expected) { 588 ZoneId test = ZoneId.of(id); 589 assertEquals(test.toString(), expected); 590 } 591 592 } | 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; 61 62 import static org.testng.Assert.assertEquals; 63 import static org.testng.Assert.fail; 64 65 import java.io.ByteArrayInputStream; 66 import java.io.ByteArrayOutputStream; 67 import java.io.DataOutputStream; 68 import java.io.ObjectInputStream; 69 import java.io.ObjectStreamConstants; 70 import java.lang.reflect.Field; 71 import java.time.DateTimeException; 72 import java.time.Instant; 73 import java.time.LocalTime; 74 import java.time.ZoneId; 75 import java.time.ZoneOffset; 76 import java.time.format.TextStyle; 77 import java.time.temporal.TemporalAccessor; 78 import java.time.temporal.TemporalField; 79 import java.time.temporal.TemporalQuery; 80 import java.time.zone.ZoneRulesException; 81 import java.util.HashMap; 82 import java.util.Locale; 83 import java.util.Map; 84 import java.util.Set; 85 86 import org.testng.annotations.DataProvider; 87 import org.testng.annotations.Test; 88 89 /** 90 * Test ZoneId. 91 */ 92 @Test 93 public class TCKZoneId extends AbstractTCKTest { 94 95 //----------------------------------------------------------------------- 96 @Test 97 public void test_serialization() throws Exception { 98 assertSerializable(ZoneId.of("Europe/London")); 99 assertSerializable(ZoneId.of("America/Chicago")); 100 } 101 102 @Test 103 public void test_serialization_format() throws Exception { 104 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 105 try (DataOutputStream dos = new DataOutputStream(baos) ) { 106 dos.writeByte(7); 107 dos.writeUTF("Europe/London"); 108 } 109 byte[] bytes = baos.toByteArray(); 110 assertSerializedBySer(ZoneId.of("Europe/London"), bytes); 111 } 112 113 @Test 114 public void test_deserialization_lenient_characters() throws Exception { 115 // an ID can be loaded without validation during deserialization 116 String id = "QWERTYUIOPASDFGHJKLZXCVBNM~/._+-"; 117 ZoneId deser = deserialize(id); 118 // getId, equals, hashCode, toString and normalized are OK 119 assertEquals(deser.getId(), id); 120 assertEquals(deser.toString(), id); 121 assertEquals(deser, deser); 122 assertEquals(deser.hashCode(), deser.hashCode()); 123 assertEquals(deser.normalized(), deser); 124 // getting the rules is not 125 try { 126 deser.getRules(); 127 fail(); 128 } catch (ZoneRulesException ex) { 129 // expected 130 } 131 } 132 133 @Test(expectedExceptions=DateTimeException.class) 134 public void test_deserialization_lenient_badCharacters() throws Exception { 135 // an ID can be loaded without validation during deserialization 136 // but there is a check to ensure the ID format is valid 137 deserialize("|!?"); 138 } 139 140 @Test(dataProvider="offsetBasedValid") 141 public void test_deserialization_lenient_offsetNotAllowed_noPrefix(String input, String resolvedId) throws Exception { 142 ZoneId deserialized = deserialize(input); 143 assertEquals(deserialized, ZoneId.of(input)); 144 assertEquals(deserialized, ZoneId.of(resolvedId)); 145 } 146 147 @Test(dataProvider="offsetBasedValidPrefix") 148 public void test_deserialization_lenient_offsetNotAllowed_prefixUTC(String input, String resolvedId, String offsetId) throws Exception { 149 ZoneId deserialized = deserialize("UTC" + input); 150 assertEquals(deserialized, ZoneId.of("UTC" + input)); 151 assertEquals(deserialized, ZoneId.of("UTC" + resolvedId)); 152 } 153 154 @Test(dataProvider="offsetBasedValidPrefix") 155 public void test_deserialization_lenient_offsetNotAllowed_prefixGMT(String input, String resolvedId, String offsetId) throws Exception { 156 ZoneId deserialized = deserialize("GMT" + input); 157 assertEquals(deserialized, ZoneId.of("GMT" + input)); 158 assertEquals(deserialized, ZoneId.of("GMT" + resolvedId)); 159 } 160 161 @Test(dataProvider="offsetBasedValidPrefix") 162 public void test_deserialization_lenient_offsetNotAllowed_prefixUT(String input, String resolvedId, String offsetId) throws Exception { 163 ZoneId deserialized = deserialize("UT" + input); 164 assertEquals(deserialized, ZoneId.of("UT" + input)); 165 assertEquals(deserialized, ZoneId.of("UT" + resolvedId)); 166 } 167 168 private ZoneId deserialize(String id) throws Exception { 169 String serClass = ZoneId.class.getPackage().getName() + ".Ser"; 170 Class<?> serCls = Class.forName(serClass); 171 Field field = serCls.getDeclaredField("serialVersionUID"); 172 field.setAccessible(true); 173 long serVer = (Long) field.get(null); 174 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 175 try (DataOutputStream dos = new DataOutputStream(baos)) { 176 dos.writeShort(ObjectStreamConstants.STREAM_MAGIC); 177 dos.writeShort(ObjectStreamConstants.STREAM_VERSION); 178 dos.writeByte(ObjectStreamConstants.TC_OBJECT); 179 dos.writeByte(ObjectStreamConstants.TC_CLASSDESC); 180 dos.writeUTF(serClass); 181 dos.writeLong(serVer); 182 dos.writeByte(ObjectStreamConstants.SC_EXTERNALIZABLE | ObjectStreamConstants.SC_BLOCK_DATA); 183 dos.writeShort(0); // number of fields 184 dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); // end of classdesc 185 dos.writeByte(ObjectStreamConstants.TC_NULL); // no superclasses 186 dos.writeByte(ObjectStreamConstants.TC_BLOCKDATA); 187 dos.writeByte(1 + 2 + id.length()); // length of data (1 byte + 2 bytes UTF length + 32 bytes UTF) 188 dos.writeByte(7); // ZoneId 189 dos.writeUTF(id); 190 dos.writeByte(ObjectStreamConstants.TC_ENDBLOCKDATA); // end of blockdata 191 } 192 ZoneId deser = null; 193 try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()))) { 194 deser = (ZoneId) ois.readObject(); 195 } 196 return deser; 197 } 198 199 //----------------------------------------------------------------------- 200 // OLD_SHORT_IDS 201 //----------------------------------------------------------------------- 202 public void test_constant_OLD_IDS_PRE_2005() { 203 Map<String, String> ids = ZoneId.OLD_SHORT_IDS; 204 assertEquals(ids.get("EST"), "America/New_York"); 205 assertEquals(ids.get("MST"), "America/Denver"); 206 assertEquals(ids.get("HST"), "Pacific/Honolulu"); 207 assertEquals(ids.get("ACT"), "Australia/Darwin"); 208 assertEquals(ids.get("AET"), "Australia/Sydney"); 209 assertEquals(ids.get("AGT"), "America/Argentina/Buenos_Aires"); 210 assertEquals(ids.get("ART"), "Africa/Cairo"); 211 assertEquals(ids.get("AST"), "America/Anchorage"); 212 assertEquals(ids.get("BET"), "America/Sao_Paulo"); 213 assertEquals(ids.get("BST"), "Asia/Dhaka"); 214 assertEquals(ids.get("CAT"), "Africa/Harare"); 215 assertEquals(ids.get("CNT"), "America/St_Johns"); 216 assertEquals(ids.get("CST"), "America/Chicago"); 217 assertEquals(ids.get("CTT"), "Asia/Shanghai"); 218 assertEquals(ids.get("EAT"), "Africa/Addis_Ababa"); 219 assertEquals(ids.get("ECT"), "Europe/Paris"); 220 assertEquals(ids.get("IET"), "America/Indiana/Indianapolis"); 221 assertEquals(ids.get("IST"), "Asia/Kolkata"); 222 assertEquals(ids.get("JST"), "Asia/Tokyo"); 223 assertEquals(ids.get("MIT"), "Pacific/Apia"); 224 assertEquals(ids.get("NET"), "Asia/Yerevan"); 225 assertEquals(ids.get("NST"), "Pacific/Auckland"); 226 assertEquals(ids.get("PLT"), "Asia/Karachi"); 227 assertEquals(ids.get("PNT"), "America/Phoenix"); 228 assertEquals(ids.get("PRT"), "America/Puerto_Rico"); 229 assertEquals(ids.get("PST"), "America/Los_Angeles"); 230 assertEquals(ids.get("SST"), "Pacific/Guadalcanal"); 231 assertEquals(ids.get("VST"), "Asia/Ho_Chi_Minh"); 232 } 233 234 @Test(expectedExceptions=UnsupportedOperationException.class) 235 public void test_constant_OLD_IDS_PRE_2005_immutable() { 236 Map<String, String> ids = ZoneId.OLD_SHORT_IDS; 237 ids.clear(); 238 } 239 240 //----------------------------------------------------------------------- 241 // SHORT_IDS 242 //----------------------------------------------------------------------- 243 public void test_constant_OLD_IDS_POST_2005() { 244 Map<String, String> ids = ZoneId.SHORT_IDS; 245 assertEquals(ids.get("EST"), "-05:00"); 246 assertEquals(ids.get("MST"), "-07:00"); 247 assertEquals(ids.get("HST"), "-10:00"); 248 assertEquals(ids.get("ACT"), "Australia/Darwin"); 249 assertEquals(ids.get("AET"), "Australia/Sydney"); 250 assertEquals(ids.get("AGT"), "America/Argentina/Buenos_Aires"); 251 assertEquals(ids.get("ART"), "Africa/Cairo"); 252 assertEquals(ids.get("AST"), "America/Anchorage"); 253 assertEquals(ids.get("BET"), "America/Sao_Paulo"); 254 assertEquals(ids.get("BST"), "Asia/Dhaka"); 255 assertEquals(ids.get("CAT"), "Africa/Harare"); 256 assertEquals(ids.get("CNT"), "America/St_Johns"); 257 assertEquals(ids.get("CST"), "America/Chicago"); 258 assertEquals(ids.get("CTT"), "Asia/Shanghai"); 259 assertEquals(ids.get("EAT"), "Africa/Addis_Ababa"); 260 assertEquals(ids.get("ECT"), "Europe/Paris"); 261 assertEquals(ids.get("IET"), "America/Indiana/Indianapolis"); 262 assertEquals(ids.get("IST"), "Asia/Kolkata"); 263 assertEquals(ids.get("JST"), "Asia/Tokyo"); 264 assertEquals(ids.get("MIT"), "Pacific/Apia"); 265 assertEquals(ids.get("NET"), "Asia/Yerevan"); 266 assertEquals(ids.get("NST"), "Pacific/Auckland"); 267 assertEquals(ids.get("PLT"), "Asia/Karachi"); 268 assertEquals(ids.get("PNT"), "America/Phoenix"); 269 assertEquals(ids.get("PRT"), "America/Puerto_Rico"); 270 assertEquals(ids.get("PST"), "America/Los_Angeles"); 271 assertEquals(ids.get("SST"), "Pacific/Guadalcanal"); 272 assertEquals(ids.get("VST"), "Asia/Ho_Chi_Minh"); 273 } 274 275 @Test(expectedExceptions=UnsupportedOperationException.class) 276 public void test_constant_OLD_IDS_POST_2005_immutable() { 277 Map<String, String> ids = ZoneId.SHORT_IDS; 278 ids.clear(); 279 } 280 281 //----------------------------------------------------------------------- 282 // getAvailableZoneIds() 283 //----------------------------------------------------------------------- 284 @Test 285 public void test_getAvailableGroupIds() { 286 Set<String> zoneIds = ZoneId.getAvailableZoneIds(); 287 assertEquals(zoneIds.contains("Europe/London"), true); 288 zoneIds.clear(); 289 assertEquals(zoneIds.size(), 0); 290 Set<String> zoneIds2 = ZoneId.getAvailableZoneIds(); 291 assertEquals(zoneIds2.contains("Europe/London"), true); 292 } 293 294 //----------------------------------------------------------------------- 295 // mapped factory 296 //----------------------------------------------------------------------- 297 @Test 298 public void test_of_string_Map() { 299 Map<String, String> map = new HashMap<>(); 300 map.put("LONDON", "Europe/London"); 301 map.put("PARIS", "Europe/Paris"); 302 ZoneId test = ZoneId.of("LONDON", map); 303 assertEquals(test.getId(), "Europe/London"); 304 } 305 306 @Test 307 public void test_of_string_Map_lookThrough() { 308 Map<String, String> map = new HashMap<>(); 309 map.put("LONDON", "Europe/London"); 310 map.put("PARIS", "Europe/Paris"); 311 ZoneId test = ZoneId.of("Europe/Madrid", map); 312 assertEquals(test.getId(), "Europe/Madrid"); 313 } 314 315 @Test 316 public void test_of_string_Map_emptyMap() { 317 Map<String, String> map = new HashMap<>(); 318 ZoneId test = ZoneId.of("Europe/Madrid", map); 319 assertEquals(test.getId(), "Europe/Madrid"); 320 } 321 322 @Test(expectedExceptions=DateTimeException.class) 323 public void test_of_string_Map_badFormat() { 324 Map<String, String> map = new HashMap<>(); 325 ZoneId.of("Not known", map); 326 } 327 328 @Test(expectedExceptions=ZoneRulesException.class) 329 public void test_of_string_Map_unknown() { 330 Map<String, String> map = new HashMap<>(); 331 ZoneId.of("Unknown", map); 332 } 333 334 //----------------------------------------------------------------------- 335 // regular factory and .normalized() 336 //----------------------------------------------------------------------- 337 @DataProvider(name="offsetBasedValid") 338 Object[][] data_offsetBasedValid() { 339 return new Object[][] { 340 {"Z", "Z"}, 341 {"+0", "Z"}, 342 {"-0", "Z"}, 343 {"+00", "Z"}, 344 {"+0000", "Z"}, 345 {"+00:00", "Z"}, 346 {"+000000", "Z"}, 347 {"+00:00:00", "Z"}, 348 {"-00", "Z"}, 349 {"-0000", "Z"}, 350 {"-00:00", "Z"}, 351 {"-000000", "Z"}, 352 {"-00:00:00", "Z"}, 353 {"+5", "+05:00"}, 354 {"+01", "+01:00"}, 355 {"+0100", "+01:00"}, 356 {"+01:00", "+01:00"}, 357 {"+010000", "+01:00"}, 358 {"+01:00:00", "+01:00"}, 359 {"+12", "+12:00"}, 360 {"+1234", "+12:34"}, 361 {"+12:34", "+12:34"}, 362 {"+123456", "+12:34:56"}, 363 {"+12:34:56", "+12:34:56"}, 364 {"-02", "-02:00"}, 365 {"-5", "-05:00"}, 366 {"-0200", "-02:00"}, 367 {"-02:00", "-02:00"}, 368 {"-020000", "-02:00"}, 369 {"-02:00:00", "-02:00"}, 370 }; 371 } 372 373 @Test(dataProvider="offsetBasedValid") 374 public void factory_of_String_offsetBasedValid_noPrefix(String input, String id) { 375 ZoneId test = ZoneId.of(input); 376 assertEquals(test.getId(), id); 377 assertEquals(test, ZoneOffset.of(id)); 378 assertEquals(test.normalized(), ZoneOffset.of(id)); 379 assertEquals(test.getDisplayName(TextStyle.FULL, Locale.UK), id); 380 assertEquals(test.getRules().isFixedOffset(), true); 381 assertEquals(test.getRules().getOffset(Instant.EPOCH), ZoneOffset.of(id)); 382 } 383 384 //----------------------------------------------------------------------- 385 @DataProvider(name="offsetBasedValidPrefix") 386 Object[][] data_offsetBasedValidPrefix() { 387 return new Object[][] { 388 {"", "", "Z"}, 389 {"+0", "", "Z"}, 390 {"-0", "", "Z"}, 391 {"+00", "", "Z"}, 392 {"+0000", "", "Z"}, 393 {"+00:00", "", "Z"}, 394 {"+000000", "", "Z"}, 395 {"+00:00:00", "", "Z"}, 396 {"-00", "", "Z"}, 397 {"-0000", "", "Z"}, 398 {"-00:00", "", "Z"}, 399 {"-000000", "", "Z"}, 400 {"-00:00:00", "", "Z"}, 401 {"+5", "+05:00", "+05:00"}, 402 {"+01", "+01:00", "+01:00"}, 403 {"+0100", "+01:00", "+01:00"}, 404 {"+01:00", "+01:00", "+01:00"}, 405 {"+010000", "+01:00", "+01:00"}, 406 {"+01:00:00", "+01:00", "+01:00"}, 407 {"+12", "+12:00", "+12:00"}, 408 {"+1234", "+12:34", "+12:34"}, 409 {"+12:34", "+12:34", "+12:34"}, 410 {"+123456", "+12:34:56", "+12:34:56"}, 411 {"+12:34:56", "+12:34:56", "+12:34:56"}, 412 {"-02", "-02:00", "-02:00"}, 413 {"-5", "-05:00", "-05:00"}, 414 {"-0200", "-02:00", "-02:00"}, 415 {"-02:00", "-02:00", "-02:00"}, 416 {"-020000", "-02:00", "-02:00"}, 417 {"-02:00:00", "-02:00", "-02:00"}, 418 }; 419 } 420 421 @Test(dataProvider="offsetBasedValidPrefix") 422 public void factory_of_String_offsetBasedValid_prefixUTC(String input, String id, String offsetId) { 423 ZoneId test = ZoneId.of("UTC" + input); 424 assertEquals(test.getId(), "UTC" + id); 425 assertEquals(test.getRules(), ZoneOffset.of(offsetId).getRules()); 426 assertEquals(test.normalized(), ZoneOffset.of(offsetId)); 427 assertEquals(test.getDisplayName(TextStyle.FULL, Locale.UK), displayName("UTC" + id)); 428 assertEquals(test.getRules().isFixedOffset(), true); 429 assertEquals(test.getRules().getOffset(Instant.EPOCH), ZoneOffset.of(offsetId)); 430 } 431 432 @Test(dataProvider="offsetBasedValidPrefix") 433 public void factory_of_String_offsetBasedValid_prefixGMT(String input, String id, String offsetId) { 434 ZoneId test = ZoneId.of("GMT" + input); 435 assertEquals(test.getId(), "GMT" + id); 436 assertEquals(test.getRules(), ZoneOffset.of(offsetId).getRules()); 437 assertEquals(test.normalized(), ZoneOffset.of(offsetId)); 438 assertEquals(test.getDisplayName(TextStyle.FULL, Locale.UK), displayName("GMT" + id)); 439 assertEquals(test.getRules().isFixedOffset(), true); 440 assertEquals(test.getRules().getOffset(Instant.EPOCH), ZoneOffset.of(offsetId)); 441 } 442 443 @Test(dataProvider="offsetBasedValidPrefix") 444 public void factory_of_String_offsetBasedValid_prefixUT(String input, String id, String offsetId) { 445 ZoneId test = ZoneId.of("UT" + input); 446 assertEquals(test.getId(), "UT" + id); 447 assertEquals(test.getRules(), ZoneOffset.of(offsetId).getRules()); 448 assertEquals(test.normalized(), ZoneOffset.of(offsetId)); 449 assertEquals(test.getDisplayName(TextStyle.FULL, Locale.UK), displayName("UT" + id)); 450 assertEquals(test.getRules().isFixedOffset(), true); 451 assertEquals(test.getRules().getOffset(Instant.EPOCH), ZoneOffset.of(offsetId)); 452 } 453 454 private String displayName(String id) { 455 if (id.equals("GMT")) { 456 return "Greenwich Mean Time"; 457 } 458 if (id.equals("GMT0")) { 459 return "Greenwich Mean Time"; 460 } 461 if (id.equals("UTC")) { 462 return "Coordinated Universal Time"; 463 } 464 return id; 465 } 466 467 //----------------------------------------------------------------------- 468 @DataProvider(name="offsetBasedValidOther") 469 Object[][] data_offsetBasedValidOther() { 470 return new Object[][] { 471 {"GMT", "Z"}, 472 {"GMT0", "Z"}, 473 {"UCT", "Z"}, 474 {"Greenwich", "Z"}, 475 {"Universal", "Z"}, 476 {"Zulu", "Z"}, 477 {"Etc/GMT", "Z"}, 478 {"Etc/GMT+0", "Z"}, 479 {"Etc/GMT+1", "-01:00"}, 480 {"Etc/GMT-1", "+01:00"}, 481 {"Etc/GMT+9", "-09:00"}, 482 {"Etc/GMT-9", "+09:00"}, 483 {"Etc/GMT0", "Z"}, 484 {"Etc/UCT", "Z"}, 485 {"Etc/UTC", "Z"}, 486 {"Etc/Greenwich", "Z"}, 487 {"Etc/Universal", "Z"}, 488 {"Etc/Zulu", "Z"}, 489 }; 490 } 491 492 @Test(dataProvider="offsetBasedValidOther") 493 public void factory_of_String_offsetBasedValidOther(String input, String offsetId) { 494 ZoneId test = ZoneId.of(input); 495 assertEquals(test.getId(), input); 496 assertEquals(test.getRules(), ZoneOffset.of(offsetId).getRules()); 497 assertEquals(test.normalized(), ZoneOffset.of(offsetId)); 498 } 499 500 //----------------------------------------------------------------------- 501 @DataProvider(name="offsetBasedInvalid") 502 Object[][] data_offsetBasedInvalid() { 503 return new Object[][] { 504 {"A"}, {"B"}, {"C"}, {"D"}, {"E"}, {"F"}, {"G"}, {"H"}, {"I"}, {"J"}, {"K"}, {"L"}, {"M"}, 505 {"N"}, {"O"}, {"P"}, {"Q"}, {"R"}, {"S"}, {"T"}, {"U"}, {"V"}, {"W"}, {"X"}, {"Y"}, {"Z"}, 506 {"+0:00"}, {"+00:0"}, {"+0:0"}, 507 {"+000"}, {"+00000"}, 508 {"+0:00:00"}, {"+00:0:00"}, {"+00:00:0"}, {"+0:0:0"}, {"+0:0:00"}, {"+00:0:0"}, {"+0:00:0"}, 509 {"+01_00"}, {"+01;00"}, {"+01@00"}, {"+01:AA"}, 510 {"+19"}, {"+19:00"}, {"+18:01"}, {"+18:00:01"}, {"+1801"}, {"+180001"}, 511 {"-0:00"}, {"-00:0"}, {"-0:0"}, 512 {"-000"}, {"-00000"}, 513 {"-0:00:00"}, {"-00:0:00"}, {"-00:00:0"}, {"-0:0:0"}, {"-0:0:00"}, {"-00:0:0"}, {"-0:00:0"}, 514 {"-19"}, {"-19:00"}, {"-18:01"}, {"-18:00:01"}, {"-1801"}, {"-180001"}, 515 {"-01_00"}, {"-01;00"}, {"-01@00"}, {"-01:AA"}, 516 {"@01:00"}, 517 {"0"}, 518 {"UT0"}, 519 {"UTZ"}, 520 {"UTC0"}, 521 {"UTCZ"}, 522 {"GMTZ"}, // GMT0 is valid in ZoneRulesProvider 523 }; 524 } 525 526 @Test(dataProvider="offsetBasedInvalid", expectedExceptions=DateTimeException.class) 527 public void factory_of_String_offsetBasedInvalid_noPrefix(String id) { 528 if (id.equals("Z")) { 529 throw new DateTimeException("Fake exception: Z alone is valid, not invalid"); 530 } 531 ZoneId.of(id); 532 } 533 534 @Test(dataProvider="offsetBasedInvalid", expectedExceptions=DateTimeException.class) 535 public void factory_of_String_offsetBasedInvalid_prefixUTC(String id) { 536 ZoneId.of("UTC" + id); 537 } 538 539 @Test(dataProvider="offsetBasedInvalid", expectedExceptions=DateTimeException.class) 540 public void factory_of_String_offsetBasedInvalid_prefixGMT(String id) { 541 if (id.equals("0")) { 542 throw new DateTimeException("Fake exception: GMT0 is valid, not invalid"); 543 } 544 ZoneId.of("GMT" + id); 545 } 546 547 @Test(dataProvider="offsetBasedInvalid", expectedExceptions=DateTimeException.class) 548 public void factory_of_String_offsetBasedInvalid_prefixUT(String id) { 549 if (id.equals("C")) { 550 throw new DateTimeException("Fake exception: UT + C = UTC, thus it is valid, not invalid"); 551 } 552 ZoneId.of("UT" + id); 553 } 554 555 //----------------------------------------------------------------------- 556 @DataProvider(name="regionBasedInvalid") 557 Object[][] data_regionBasedInvalid() { 558 // \u00ef is a random unicode character 559 return new Object[][] { 560 {""}, {":"}, {"#"}, 561 {"\u00ef"}, {"`"}, {"!"}, {"\""}, {"\u00ef"}, {"$"}, {"^"}, {"&"}, {"*"}, {"("}, {")"}, {"="}, 562 {"\\"}, {"|"}, {","}, {"<"}, {">"}, {"?"}, {";"}, {"'"}, {"["}, {"]"}, {"{"}, {"}"}, 563 {"\u00ef:A"}, {"`:A"}, {"!:A"}, {"\":A"}, {"\u00ef:A"}, {"$:A"}, {"^:A"}, {"&:A"}, {"*:A"}, {"(:A"}, {"):A"}, {"=:A"}, {"+:A"}, 564 {"\\:A"}, {"|:A"}, {",:A"}, {"<:A"}, {">:A"}, {"?:A"}, {";:A"}, {"::A"}, {"':A"}, {"@:A"}, {"~:A"}, {"[:A"}, {"]:A"}, {"{:A"}, {"}:A"}, 565 {"A:B#\u00ef"}, {"A:B#`"}, {"A:B#!"}, {"A:B#\""}, {"A:B#\u00ef"}, {"A:B#$"}, {"A:B#^"}, {"A:B#&"}, {"A:B#*"}, 566 {"A:B#("}, {"A:B#)"}, {"A:B#="}, {"A:B#+"}, 567 {"A:B#\\"}, {"A:B#|"}, {"A:B#,"}, {"A:B#<"}, {"A:B#>"}, {"A:B#?"}, {"A:B#;"}, {"A:B#:"}, 568 {"A:B#'"}, {"A:B#@"}, {"A:B#~"}, {"A:B#["}, {"A:B#]"}, {"A:B#{"}, {"A:B#}"}, 569 }; 570 } 571 572 @Test(dataProvider="regionBasedInvalid", expectedExceptions=DateTimeException.class) 573 public void factory_of_String_regionBasedInvalid(String id) { 574 ZoneId.of(id); 575 } 576 577 //----------------------------------------------------------------------- 578 @Test 579 public void factory_of_String_region_EuropeLondon() { 580 ZoneId test = ZoneId.of("Europe/London"); 581 assertEquals(test.getId(), "Europe/London"); 582 assertEquals(test.getRules().isFixedOffset(), false); 583 assertEquals(test.normalized(), test); 584 } 585 586 //----------------------------------------------------------------------- 587 @Test(expectedExceptions=NullPointerException.class) 588 public void factory_of_String_null() { 589 ZoneId.of(null); 590 } 591 592 @Test(expectedExceptions=DateTimeException.class) 593 public void factory_of_String_badFormat() { 594 ZoneId.of("Unknown rule"); 595 } 596 597 @Test(expectedExceptions=ZoneRulesException.class) 598 public void factory_of_String_unknown() { 599 ZoneId.of("Unknown"); 600 } 601 602 //----------------------------------------------------------------------- 603 // from(TemporalAccessor) 604 //----------------------------------------------------------------------- 605 @Test 606 public void factory_from_TemporalAccessor_zoneId() { 607 TemporalAccessor mock = new TemporalAccessor() { 608 @Override 609 public boolean isSupported(TemporalField field) { 610 return false; 611 } 612 @Override 613 public long getLong(TemporalField field) { 614 throw new DateTimeException("Mock"); 615 } 616 @SuppressWarnings("unchecked") 617 @Override 618 public <R> R query(TemporalQuery<R> query) { 619 if (query == TemporalQuery.zoneId()) { 620 return (R) ZoneId.of("Europe/Paris"); 621 } 622 return TemporalAccessor.super.query(query); 623 } 624 }; 625 assertEquals(ZoneId.from(mock), ZoneId.of("Europe/Paris")); 626 } 627 628 @Test 629 public void factory_from_TemporalAccessor_offset() { 630 ZoneOffset offset = ZoneOffset.ofHours(1); 631 assertEquals(ZoneId.from(offset), offset); 632 } 633 634 @Test(expectedExceptions=DateTimeException.class) 635 public void factory_from_TemporalAccessor_invalid_noDerive() { 636 ZoneId.from(LocalTime.of(12, 30)); 637 } 638 639 @Test(expectedExceptions=NullPointerException.class) 663 664 @Test 665 public void test_equals_null() { 666 assertEquals(ZoneId.of("Europe/London").equals(null), false); 667 } 668 669 @Test 670 public void test_equals_notEqualWrongType() { 671 assertEquals(ZoneId.of("Europe/London").equals("Europe/London"), false); 672 } 673 674 //----------------------------------------------------------------------- 675 // toString() 676 //----------------------------------------------------------------------- 677 @DataProvider(name="toString") 678 Object[][] data_toString() { 679 return new Object[][] { 680 {"Europe/London", "Europe/London"}, 681 {"Europe/Paris", "Europe/Paris"}, 682 {"Europe/Berlin", "Europe/Berlin"}, 683 {"Z", "Z"}, 684 {"+01:00", "+01:00"}, 685 {"UTC", "UTC"}, 686 {"UTC+01:00", "UTC+01:00"}, 687 }; 688 } 689 690 @Test(dataProvider="toString") 691 public void test_toString(String id, String expected) { 692 ZoneId test = ZoneId.of(id); 693 assertEquals(test.toString(), expected); 694 } 695 696 } |