@@ -519,14 +519,42 @@ private static String replaceZeroOffsetAsZ(String text)
519519 }
520520
521521 // @since 2.13
522- private String addInColonToOffsetIfMissing (String text )
522+ private static String addInColonToOffsetIfMissing (String text )
523523 {
524- final Matcher matcher = ISO8601_COLONLESS_OFFSET_REGEX .matcher (text );
525- if (matcher .find ()){
526- StringBuilder sb = new StringBuilder (matcher .group (0 ));
527- sb .insert (3 , ":" );
524+ int timeIndex = text .indexOf ('T' );
525+ if (timeIndex < 0 || timeIndex > text .length () - 1 ) {
526+ return text ;
527+ }
528+
529+ int offsetIndex = text .indexOf ('+' , timeIndex + 1 );
530+ if (offsetIndex < 0 ) {
531+ offsetIndex = text .indexOf ('-' , timeIndex + 1 );
532+ }
533+
534+ if (offsetIndex < 0 || offsetIndex > text .length () - 5 ) {
535+ return text ;
536+ }
537+
538+ int colonIndex = text .indexOf (':' , offsetIndex );
539+ if (colonIndex == offsetIndex + 3 ) {
540+ return text ;
541+ }
528542
529- return matcher .replaceFirst (sb .toString ());
543+ if (Character .isDigit (text .charAt (offsetIndex + 1 ))
544+ && Character .isDigit (text .charAt (offsetIndex + 2 ))
545+ && Character .isDigit (text .charAt (offsetIndex + 3 ))
546+ && Character .isDigit (text .charAt (offsetIndex + 4 ))) {
547+ String match = text .substring (offsetIndex , offsetIndex + 5 );
548+ return text .substring (0 , offsetIndex )
549+ + match .substring (0 , 3 ) + ':' + match .substring (3 )
550+ + text .substring (offsetIndex + match .length ());
551+ }
552+
553+ // fallback to slow regex path, should be fully handled by the above
554+ final Matcher matcher = ISO8601_COLONLESS_OFFSET_REGEX .matcher (text );
555+ if (matcher .find ()) {
556+ String match = matcher .group (0 );
557+ return matcher .replaceFirst (match .substring (0 , 3 ) + ':' + match .substring (3 ));
530558 }
531559 return text ;
532560 }
0 commit comments