Skip to content

Commit 0a20188

Browse files
committed
Fix basic parsing where additional plus sign
Based on code by Hari Shankar - https://github.com/hshankar Fixes #86
1 parent 4289f5e commit 0a20188

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

RELEASE-NOTES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Changes in 2.8.3
2020

2121
- Faster parsing of time-zone identifiers [#282]
2222

23+
- Fix parsing of basic form ISO style where year has unnecessary plus sign [#86]
24+
For example, +20151030 will now be correctly parsed as year 2015.
25+
2326
- Added Interval.parseWithOffset(String) [#299, #296]
2427
Provides a way to parse the fixed offset in an interval string
2528

src/main/java/org/joda/time/format/DateTimeFormatterBuilder.java

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,25 +1304,21 @@ public int parseInto(DateTimeParserBucket bucket, CharSequence text, int positio
13041304
int limit = Math.min(iMaxParsedDigits, text.length() - position);
13051305

13061306
boolean negative = false;
1307+
boolean positive = false;
13071308
int length = 0;
13081309
while (length < limit) {
13091310
char c = text.charAt(position + length);
13101311
if (length == 0 && (c == '-' || c == '+') && iSigned) {
13111312
negative = c == '-';
1313+
positive = c == '+';
13121314

13131315
// Next character must be a digit.
13141316
if (length + 1 >= limit ||
1315-
(c = text.charAt(position + length + 1)) < '0' || c > '9')
1316-
{
1317+
(c = text.charAt(position + length + 1)) < '0' || c > '9') {
13171318
break;
13181319
}
1320+
length++;
13191321

1320-
if (negative) {
1321-
length++;
1322-
} else {
1323-
// Skip the '+' for parseInt to succeed.
1324-
position++;
1325-
}
13261322
// Expand the limit to disregard the sign character.
13271323
limit = Math.min(limit + 1, text.length() - position);
13281324
continue;
@@ -1341,10 +1337,15 @@ public int parseInto(DateTimeParserBucket bucket, CharSequence text, int positio
13411337
if (length >= 9) {
13421338
// Since value may exceed integer limits, use stock parser
13431339
// which checks for this.
1344-
value = Integer.parseInt(text.subSequence(position, position += length).toString());
1340+
if (positive) {
1341+
value = Integer.parseInt(text.subSequence(position + 1, position += length).toString());
1342+
} else {
1343+
value = Integer.parseInt(text.subSequence(position, position += length).toString());
1344+
}
1345+
// value = Integer.parseInt(text.subSequence(position, position += length).toString());
13451346
} else {
13461347
int i = position;
1347-
if (negative) {
1348+
if (negative || positive) {
13481349
i++;
13491350
}
13501351
try {

src/test/java/org/joda/time/format/TestISODateTimeFormatParsing.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,15 @@ protected void tearDown() throws Exception {
6969
public void test_dateParser() {
7070
DateTimeFormatter parser = ISODateTimeFormat.dateParser();
7171
assertParse(parser, true, "2006-06-09");
72+
assertParse(parser, true, "+2006-06-09");
7273
assertParse(parser, true, "2006-W27-3");
7374
assertParse(parser, true, "2006-123");
7475
assertParse(parser, true, "2006-06-09T+02:00");
7576
assertParse(parser, true, "2006-W27-3T+02:00");
7677
assertParse(parser, true, "2006-123T+02:00");
7778

7879
assertParse(parser, false, "2006-06-09T10:20:30.040");
80+
assertParse(parser, false, "+2006-06-09T10:20:30.040");
7981
assertParse(parser, false, "2006-W27-3T10:20:30.040");
8082
assertParse(parser, false, "2006-123T10:20:30.040");
8183
assertParse(parser, false, "2006-06-09T10:20:30.040+02:00");
@@ -100,6 +102,7 @@ public void test_localDateParser() {
100102
DateTimeFormatter parser = ISODateTimeFormat.localDateParser();
101103
assertEquals(DateTimeZone.UTC, parser.getZone());
102104
assertParse(parser, true, "2006-06-09");
105+
assertParse(parser, true, "+2006-06-09");
103106
assertParse(parser, true, "2006-W27-3");
104107
assertParse(parser, true, "2006-123");
105108
assertParse(parser, false, "2006-06-09T+02:00");
@@ -133,6 +136,7 @@ public void test_dateElementParser() {
133136
assertParse(parser, "2006-06-9", new DateTime(2006, 6, 9, 0, 0, 0, 0));
134137
assertParse(parser, "2006-6-09", new DateTime(2006, 6, 9, 0, 0, 0, 0));
135138
assertParse(parser, "2006-6-9", new DateTime(2006, 6, 9, 0, 0, 0, 0));
139+
assertParse(parser, "+2006-06-09", new DateTime(2006, 6, 9, 0, 0, 0, 0));
136140
assertParse(parser, true, "2006-W27-3");
137141
assertParse(parser, true, "2006-123");
138142
assertParse(parser, false, "2006-06-09T+02:00");
@@ -361,6 +365,7 @@ public void test_date() {
361365
assertParse(parser, "2006-2-04", new DateTime(2006, 2, 4, 0, 0, 0, 0));
362366
assertParse(parser, "2006-02-4", new DateTime(2006, 2, 4, 0, 0, 0, 0));
363367
assertParse(parser, "2006-2-4", new DateTime(2006, 2, 4, 0, 0, 0, 0));
368+
assertParse(parser, "+2006-02-04", new DateTime(2006, 2, 4, 0, 0, 0, 0));
364369
assertParse(parser, false, "2006-02-");
365370
assertParse(parser, false, "2006-02");
366371
assertParse(parser, false, "2006--4");
@@ -434,6 +439,7 @@ public void test_dateTime() {
434439
assertParse(parser, "2006-2-04T10:20:30.400Z", new DateTime(2006, 2, 4, 10, 20, 30, 400));
435440
assertParse(parser, "2006-2-4T10:20:30.400Z", new DateTime(2006, 2, 4, 10, 20, 30, 400));
436441
assertParse(parser, "2006-02-04T5:6:7.800Z", new DateTime(2006, 2, 4, 5, 6, 7, 800));
442+
assertParse(parser, "+2006-02-04T5:6:7.800Z", new DateTime(2006, 2, 4, 5, 6, 7, 800));
437443
assertParse(parser, false, "2006-02-T10:20:30.400Z");
438444
assertParse(parser, false, "2006-12T10:20:30.400Z");
439445
assertParse(parser, false, "2006-1T10:20:30.400Z");
@@ -456,6 +462,7 @@ public void test_dateTimeNoMillis() {
456462
assertParse(parser, "2006-2-04T10:20:30Z", new DateTime(2006, 2, 4, 10, 20, 30, 0));
457463
assertParse(parser, "2006-2-4T10:20:30Z", new DateTime(2006, 2, 4, 10, 20, 30, 0));
458464
assertParse(parser, "2006-02-04T5:6:7Z", new DateTime(2006, 2, 4, 5, 6, 7, 0));
465+
assertParse(parser, "+2006-02-04T5:6:7Z", new DateTime(2006, 2, 4, 5, 6, 7, 0));
459466
assertParse(parser, false, "2006-02-T10:20:30Z");
460467
assertParse(parser, false, "2006-12T10:20:30Z");
461468
assertParse(parser, false, "2006-1T10:20:30Z");
@@ -475,6 +482,7 @@ public void test_ordinalDate() {
475482
assertParse(parser, "2006-123", new DateTime(2006, 1, 1, 0, 0, 0, 0).withDayOfYear(123));
476483
assertParse(parser, "2006-12", new DateTime(2006, 1, 1, 0, 0, 0, 0).withDayOfYear(12));
477484
assertParse(parser, "2006-1", new DateTime(2006, 1, 1, 0, 0, 0, 0).withDayOfYear(1));
485+
assertParse(parser, "+2006-123", new DateTime(2006, 1, 1, 0, 0, 0, 0).withDayOfYear(123));
478486
assertParse(parser, false, "2006-");
479487
assertParse(parser, false, "2006");
480488
}
@@ -490,6 +498,7 @@ public void test_ordinalDateTime() {
490498
assertParse(parser, "2006-12T10:20:30.400Z", new DateTime(2006, 1, 1, 10, 20, 30, 400).withDayOfYear(12));
491499
assertParse(parser, "2006-1T10:20:30.400Z", new DateTime(2006, 1, 1, 10, 20, 30, 400).withDayOfYear(1));
492500
assertParse(parser, "2006-123T5:6:7.800Z", new DateTime(2006, 1, 1, 5, 6, 7, 800).withDayOfYear(123));
501+
assertParse(parser, "+2006-123T5:6:7.800Z", new DateTime(2006, 1, 1, 5, 6, 7, 800).withDayOfYear(123));
493502
assertParse(parser, false, "2006-T10:20:30.400Z");
494503
assertParse(parser, false, "2006T10:20:30.400Z");
495504
assertParse(parser, false, "2006-123T10:20.400Z");
@@ -506,6 +515,7 @@ public void test_ordinalDateTimeNoMillis() {
506515
assertParse(parser, "2006-12T10:20:30Z", new DateTime(2006, 1, 1, 10, 20, 30, 0).withDayOfYear(12));
507516
assertParse(parser, "2006-1T10:20:30Z", new DateTime(2006, 1, 1, 10, 20, 30, 0).withDayOfYear(1));
508517
assertParse(parser, "2006-123T5:6:7Z", new DateTime(2006, 1, 1, 5, 6, 7, 0).withDayOfYear(123));
518+
assertParse(parser, "+2006-123T5:6:7Z", new DateTime(2006, 1, 1, 5, 6, 7, 0).withDayOfYear(123));
509519
assertParse(parser, false, "2006-T10:20:30Z");
510520
assertParse(parser, false, "2006T10:20:30Z");
511521
assertParse(parser, false, "2006-123T10:20Z");
@@ -519,6 +529,7 @@ public void test_weekDate() {
519529
DateTimeFormatter parser = ISODateTimeFormat.weekDate();
520530
assertParse(parser, "2006-W27-3", new DateTime(2006, 6, 1, 0, 0, 0, 0).withWeekOfWeekyear(27).withDayOfWeek(3));
521531
assertParse(parser, "2006-W2-3", new DateTime(2006, 6, 1, 0, 0, 0, 0).withWeekOfWeekyear(2).withDayOfWeek(3));
532+
assertParse(parser, "+2006-W27-3", new DateTime(2006, 6, 1, 0, 0, 0, 0).withWeekOfWeekyear(27).withDayOfWeek(3));
522533
assertParse(parser, false, "2006-W-3");
523534
assertParse(parser, false, "2006-W27-");
524535
assertParse(parser, false, "2006-W27");
@@ -536,6 +547,7 @@ public void test_weekDateTime() {
536547
assertParse(parser, "2006-W27-3T10:20:30.4Z", new DateTime(2006, 6, 1, 10, 20, 30, 400).withWeekOfWeekyear(27).withDayOfWeek(3));
537548
assertParse(parser, "2006-W2-3T10:20:30.400Z", new DateTime(2006, 6, 1, 10, 20, 30, 400).withWeekOfWeekyear(2).withDayOfWeek(3));
538549
assertParse(parser, "2006-W27-3T5:6:7.800Z", new DateTime(2006, 6, 1, 5, 6, 7, 800).withWeekOfWeekyear(27).withDayOfWeek(3));
550+
assertParse(parser, "+2006-W27-3T5:6:7.800Z", new DateTime(2006, 6, 1, 5, 6, 7, 800).withWeekOfWeekyear(27).withDayOfWeek(3));
539551
assertParse(parser, false, "2006-W27-T10:20:30.400Z");
540552
assertParse(parser, false, "2006-W27T10:20:30.400Z");
541553
assertParse(parser, false, "2006-W2T10:20:30.400Z");
@@ -553,6 +565,7 @@ public void test_weekDateTimeNoMillis() {
553565
assertParse(parser, "2006-W27-3T10:20:30Z", new DateTime(2006, 6, 1, 10, 20, 30, 0).withWeekOfWeekyear(27).withDayOfWeek(3));
554566
assertParse(parser, "2006-W2-3T10:20:30Z", new DateTime(2006, 6, 1, 10, 20, 30, 0).withWeekOfWeekyear(2).withDayOfWeek(3));
555567
assertParse(parser, "2006-W27-3T5:6:7Z", new DateTime(2006, 6, 1, 5, 6, 7, 0).withWeekOfWeekyear(27).withDayOfWeek(3));
568+
assertParse(parser, "+2006-W27-3T5:6:7Z", new DateTime(2006, 6, 1, 5, 6, 7, 0).withWeekOfWeekyear(27).withDayOfWeek(3));
556569
assertParse(parser, false, "2006-W27-T10:20:30Z");
557570
assertParse(parser, false, "2006-W27T10:20:30Z");
558571
assertParse(parser, false, "2006-W2T10:20:30Z");
@@ -569,6 +582,7 @@ public void test_weekDateTimeNoMillis() {
569582
public void test_basicDate() {
570583
DateTimeFormatter parser = ISODateTimeFormat.basicDate();
571584
assertParse(parser, "20060204", new DateTime(2006, 2, 4, 0, 0, 0, 0));
585+
assertParse(parser, "+20060204", new DateTime(2006, 2, 4, 0, 0, 0, 0));
572586
assertParse(parser, false, "2006024");
573587
assertParse(parser, false, "200602");
574588
assertParse(parser, false, "20061");
@@ -637,6 +651,7 @@ public void test_basicDateTime() {
637651
assertParse(parser, "20061204T102030.400Z", new DateTime(2006, 12, 4, 10, 20, 30, 400));
638652
assertParse(parser, "20061204T102030.40Z", new DateTime(2006, 12, 4, 10, 20, 30, 400));
639653
assertParse(parser, "20061204T102030.4Z", new DateTime(2006, 12, 4, 10, 20, 30, 400));
654+
assertParse(parser, "+20061204T102030.4Z", new DateTime(2006, 12, 4, 10, 20, 30, 400));
640655
assertParse(parser, false, "2006120T102030.400Z");
641656
assertParse(parser, false, "200612T102030.400Z");
642657
assertParse(parser, false, "20061T102030.400Z");
@@ -656,6 +671,7 @@ public void test_basicDateTimeNoMillis() {
656671
DateTimeZone.setDefault(DateTimeZone.UTC);
657672
DateTimeFormatter parser = ISODateTimeFormat.basicDateTimeNoMillis();
658673
assertParse(parser, "20061204T102030Z", new DateTime(2006, 12, 4, 10, 20, 30, 0));
674+
assertParse(parser, "+20061204T102030Z", new DateTime(2006, 12, 4, 10, 20, 30, 0));
659675
assertParse(parser, false, "2006120T102030Z");
660676
assertParse(parser, false, "200612T102030Z");
661677
assertParse(parser, false, "20061T102030Z");
@@ -674,6 +690,7 @@ public void test_basicDateTimeNoMillis() {
674690
public void test_basicOrdinalDate() {
675691
DateTimeFormatter parser = ISODateTimeFormat.basicOrdinalDate();
676692
assertParse(parser, "2006123", new DateTime(2006, 1, 1, 0, 0, 0, 0).withDayOfYear(123));
693+
assertParse(parser, "+2006123", new DateTime(2006, 1, 1, 0, 0, 0, 0).withDayOfYear(123));
677694
assertParse(parser, false, "200612");
678695
assertParse(parser, false, "20061");
679696
assertParse(parser, false, "2006");
@@ -687,6 +704,7 @@ public void test_basicOrdinalDateTime() {
687704
assertParse(parser, "2006123T102030.400Z", new DateTime(2006, 1, 1, 10, 20, 30, 400).withDayOfYear(123));
688705
assertParse(parser, "2006123T102030.40Z", new DateTime(2006, 1, 1, 10, 20, 30, 400).withDayOfYear(123));
689706
assertParse(parser, "2006123T102030.4Z", new DateTime(2006, 1, 1, 10, 20, 30, 400).withDayOfYear(123));
707+
assertParse(parser, "+2006123T102030.4Z", new DateTime(2006, 1, 1, 10, 20, 30, 400).withDayOfYear(123));
690708
assertParse(parser, false, "200612T102030.400Z");
691709
assertParse(parser, false, "20061T102030.400Z");
692710
assertParse(parser, false, "2006T102030.400Z");
@@ -705,6 +723,7 @@ public void test_basicOrdinalDateTimeNoMillis() {
705723
DateTimeZone.setDefault(DateTimeZone.UTC);
706724
DateTimeFormatter parser = ISODateTimeFormat.basicOrdinalDateTimeNoMillis();
707725
assertParse(parser, "2006123T102030Z", new DateTime(2006, 1, 1, 10, 20, 30, 0).withDayOfYear(123));
726+
assertParse(parser, "+2006123T102030Z", new DateTime(2006, 1, 1, 10, 20, 30, 0).withDayOfYear(123));
708727
assertParse(parser, false, "200612T102030Z");
709728
assertParse(parser, false, "20061T102030Z");
710729
assertParse(parser, false, "2006T102030Z");
@@ -722,6 +741,7 @@ public void test_basicOrdinalDateTimeNoMillis() {
722741
public void test_basicWeekDate() {
723742
DateTimeFormatter parser = ISODateTimeFormat.basicWeekDate();
724743
assertParse(parser, "2006W273", new DateTime(2006, 6, 1, 0, 0, 0, 0).withWeekOfWeekyear(27).withDayOfWeek(3));
744+
assertParse(parser, "+2006W273", new DateTime(2006, 6, 1, 0, 0, 0, 0).withWeekOfWeekyear(27).withDayOfWeek(3));
725745
assertParse(parser, false, "2006W27");
726746
assertParse(parser, false, "2006W2");
727747
assertParse(parser, false, "2006W");
@@ -735,6 +755,7 @@ public void test_basicWeekDateTime() {
735755
assertParse(parser, "2006W273T102030.400Z", new DateTime(2006, 6, 1, 10, 20, 30, 400).withWeekOfWeekyear(27).withDayOfWeek(3));
736756
assertParse(parser, "2006W273T102030.40Z", new DateTime(2006, 6, 1, 10, 20, 30, 400).withWeekOfWeekyear(27).withDayOfWeek(3));
737757
assertParse(parser, "2006W273T102030.4Z", new DateTime(2006, 6, 1, 10, 20, 30, 400).withWeekOfWeekyear(27).withDayOfWeek(3));
758+
assertParse(parser, "+2006W273T102030.4Z", new DateTime(2006, 6, 1, 10, 20, 30, 400).withWeekOfWeekyear(27).withDayOfWeek(3));
738759
assertParse(parser, false, "2006W27T102030.400Z");
739760
assertParse(parser, false, "2006W2T102030.400Z");
740761
assertParse(parser, false, "2006W273T10203.400Z");
@@ -749,6 +770,7 @@ public void test_basicWeekDateTimeNoMillis() {
749770
DateTimeZone.setDefault(DateTimeZone.UTC);
750771
DateTimeFormatter parser = ISODateTimeFormat.basicWeekDateTimeNoMillis();
751772
assertParse(parser, "2006W273T102030Z", new DateTime(2006, 6, 1, 10, 20, 30, 0).withWeekOfWeekyear(27).withDayOfWeek(3));
773+
assertParse(parser, "+2006W273T102030Z", new DateTime(2006, 6, 1, 10, 20, 30, 0).withWeekOfWeekyear(27).withDayOfWeek(3));
752774
assertParse(parser, false, "2006W27T102030Z");
753775
assertParse(parser, false, "2006W2T102030Z");
754776
assertParse(parser, false, "2006W273T10203Z");

0 commit comments

Comments
 (0)