62
62
import java .util .ResourceBundle ;
63
63
import java .util .Set ;
64
64
import java .util .TimeZone ;
65
+ import java .util .TreeMap ;
65
66
66
67
import org .threeten .bp .DateTimeException ;
67
68
import org .threeten .bp .Instant ;
@@ -3342,7 +3343,17 @@ public int parse(DateTimeParseContext context, CharSequence text, int position)
3342
3343
* Prints or parses a zone ID.
3343
3344
*/
3344
3345
static final class ZoneTextPrinterParser implements DateTimePrinterParser {
3345
- // TODO: remove this as it is incomplete
3346
+ /** The text style to output. */
3347
+ private static final Comparator <String > LENGTH_COMPARATOR = new Comparator <String >() {
3348
+ @ Override
3349
+ public int compare (String str1 , String str2 ) {
3350
+ int cmp = str2 .length () - str1 .length ();
3351
+ if (cmp == 0 ) {
3352
+ cmp = str1 .compareTo (str2 );
3353
+ }
3354
+ return cmp ;
3355
+ }
3356
+ };
3346
3357
/** The text style to output. */
3347
3358
private final TextStyle textStyle ;
3348
3359
@@ -3378,7 +3389,24 @@ public boolean print(DateTimePrintContext context, StringBuilder buf) {
3378
3389
3379
3390
@ Override
3380
3391
public int parse (DateTimeParseContext context , CharSequence text , int position ) {
3381
- throw new UnsupportedOperationException ();
3392
+ // this is a poor implementation that handles some but not all of the spec
3393
+ // JDK8 has a lot of extra information here
3394
+ Map <String , String > ids = new TreeMap <>(LENGTH_COMPARATOR );
3395
+ for (String id : ZoneId .getAvailableZoneIds ()) {
3396
+ ids .put (id , id );
3397
+ TimeZone tz = TimeZone .getTimeZone (id );
3398
+ int tzstyle = (textStyle .asNormal () == TextStyle .FULL ? TimeZone .LONG : TimeZone .SHORT );
3399
+ ids .put (tz .getDisplayName (false , tzstyle , context .getLocale ()), id );
3400
+ ids .put (tz .getDisplayName (true , tzstyle , context .getLocale ()), id );
3401
+ }
3402
+ for (Entry <String , String > entry : ids .entrySet ()) {
3403
+ String name = entry .getKey ();
3404
+ if (context .subSequenceEquals (text , position , name , 0 , name .length ())) {
3405
+ context .setParsed (ZoneId .of (entry .getValue ()));
3406
+ return position + name .length ();
3407
+ }
3408
+ }
3409
+ return ~position ;
3382
3410
}
3383
3411
3384
3412
@ Override
@@ -3429,7 +3457,6 @@ public boolean print(DateTimePrintContext context, StringBuilder buf) {
3429
3457
*/
3430
3458
@ Override
3431
3459
public int parse (DateTimeParseContext context , CharSequence text , int position ) {
3432
- // TODO case insensitive?
3433
3460
int length = text .length ();
3434
3461
if (position > length ) {
3435
3462
throw new IndexOutOfBoundsException ();
@@ -3489,20 +3516,36 @@ public int parse(DateTimeParseContext context, CharSequence text, int position)
3489
3516
break ;
3490
3517
}
3491
3518
parsedZoneId = text .subSequence (position , position + nodeLength ).toString ();
3492
- tree = tree .get (parsedZoneId );
3519
+ tree = tree .get (parsedZoneId , context . isCaseSensitive () );
3493
3520
}
3494
-
3495
- if (parsedZoneId == null || regionIds . contains ( parsedZoneId ) == false ) {
3521
+ ZoneId zone = convertToZone ( regionIds , parsedZoneId , context . isCaseSensitive ());
3522
+ if (zone == null ) {
3496
3523
if (context .charEquals (nextChar , 'Z' )) {
3497
3524
context .setParsed (ZoneOffset .UTC );
3498
3525
return position + 1 ;
3499
3526
}
3500
3527
return ~position ;
3501
3528
}
3502
- context .setParsed (ZoneId . of ( parsedZoneId ) );
3529
+ context .setParsed (zone );
3503
3530
return position + parsedZoneId .length ();
3504
3531
}
3505
3532
3533
+ private ZoneId convertToZone (Set <String > regionIds , String parsedZoneId , boolean caseSensitive ) {
3534
+ if (parsedZoneId == null ) {
3535
+ return null ;
3536
+ }
3537
+ if (caseSensitive ) {
3538
+ return (regionIds .contains (parsedZoneId ) ? ZoneId .of (parsedZoneId ) : null );
3539
+ } else {
3540
+ for (String regionId : regionIds ) {
3541
+ if (regionId .equalsIgnoreCase (parsedZoneId )) {
3542
+ return ZoneId .of (regionId );
3543
+ }
3544
+ }
3545
+ return null ;
3546
+ }
3547
+ }
3548
+
3506
3549
private int parsePrefixedOffset (DateTimeParseContext context , CharSequence text , int prefixPos , int position ) {
3507
3550
String prefix = text .subSequence (prefixPos , position ).toString ().toUpperCase ();
3508
3551
DateTimeParseContext newContext = context .copy ();
@@ -3553,6 +3596,10 @@ private static final class SubstringTree {
3553
3596
* Map of a substring to a set of substrings that contain the key.
3554
3597
*/
3555
3598
private final Map <CharSequence , SubstringTree > substringMap = new HashMap <>();
3599
+ /**
3600
+ * Map of a substring to a set of substrings that contain the key.
3601
+ */
3602
+ private final Map <String , SubstringTree > substringMapCI = new HashMap <>();
3556
3603
3557
3604
/**
3558
3605
* Constructor.
@@ -3563,9 +3610,12 @@ private SubstringTree(int length) {
3563
3610
this .length = length ;
3564
3611
}
3565
3612
3566
- private SubstringTree get (CharSequence substring2 ) {
3567
- return substringMap .get (substring2 );
3568
-
3613
+ private SubstringTree get (CharSequence substring2 , boolean caseSensitive ) {
3614
+ if (caseSensitive ) {
3615
+ return substringMap .get (substring2 );
3616
+ } else {
3617
+ return substringMapCI .get (substring2 .toString ().toLowerCase (Locale .ENGLISH ));
3618
+ }
3569
3619
}
3570
3620
3571
3621
/**
@@ -3577,12 +3627,14 @@ private void add(String newSubstring) {
3577
3627
int idLen = newSubstring .length ();
3578
3628
if (idLen == length ) {
3579
3629
substringMap .put (newSubstring , null );
3630
+ substringMapCI .put (newSubstring .toLowerCase (Locale .ENGLISH ), null );
3580
3631
} else if (idLen > length ) {
3581
3632
String substring = newSubstring .substring (0 , length );
3582
3633
SubstringTree parserTree = substringMap .get (substring );
3583
3634
if (parserTree == null ) {
3584
3635
parserTree = new SubstringTree (idLen );
3585
3636
substringMap .put (substring , parserTree );
3637
+ substringMapCI .put (substring .toLowerCase (Locale .ENGLISH ), parserTree );
3586
3638
}
3587
3639
parserTree .add (newSubstring );
3588
3640
}
0 commit comments