1 /*
2 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
1474 default:
1475 // Peek the next pattern to determine if we need to
1476 // obey the number of pattern letters for
1477 // parsing. It's required when parsing contiguous
1478 // digit text (e.g., "20010704") with a pattern which
1479 // has no delimiters between fields, like "yyyyMMdd".
1480 boolean obeyCount = false;
1481
1482 // In Arabic, a minus sign for a negative number is put after
1483 // the number. Even in another locale, a minus sign can be
1484 // put after a number using DateFormat.setNumberFormat().
1485 // If both the minus sign and the field-delimiter are '-',
1486 // subParse() needs to determine whether a '-' after a number
1487 // in the given text is a delimiter or is a minus sign for the
1488 // preceding number. We give subParse() a clue based on the
1489 // information in compiledPattern.
1490 boolean useFollowingMinusSignAsDelimiter = false;
1491
1492 if (i < compiledPattern.length) {
1493 int nextTag = compiledPattern[i] >>> 8;
1494 if (!(nextTag == TAG_QUOTE_ASCII_CHAR ||
1495 nextTag == TAG_QUOTE_CHARS)) {
1496 obeyCount = true;
1497 }
1498
1499 if (hasFollowingMinusSign &&
1500 (nextTag == TAG_QUOTE_ASCII_CHAR ||
1501 nextTag == TAG_QUOTE_CHARS)) {
1502 int c;
1503 if (nextTag == TAG_QUOTE_ASCII_CHAR) {
1504 c = compiledPattern[i] & 0xff;
1505 } else {
1506 c = compiledPattern[i+1];
1507 }
1508
1509 if (c == minusSign) {
1510 useFollowingMinusSignAsDelimiter = true;
1511 }
1512 }
1513 }
1514 start = subParse(text, start, tag, count, obeyCount,
1515 ambiguousYear, pos,
1516 useFollowingMinusSignAsDelimiter, calb);
1517 if (start < 0) {
1518 pos.index = oldStart;
1519 return null;
1520 }
1521 }
1522 }
1523
1524 // At this point the fields of Calendar have been set. Calendar
1525 // will fill in default values for missing fields when the time
1526 // is computed.
1527
1528 pos.index = start;
1529
1530 Date parsedDate;
1531 try {
1532 parsedDate = calb.establish(calendar).getTime();
1533 // If the year value is ambiguous,
1534 // then the two-digit year == the default start year
1535 if (ambiguousYear[0]) {
1536 if (parsedDate.before(defaultCenturyStart)) {
1537 parsedDate = calb.addYear(100).establish(calendar).getTime();
1538 }
1539 }
1540 }
1541 // An IllegalArgumentException will be thrown by Calendar.getTime()
1542 // if any fields are out of range, e.g., MONTH == 17.
1543 catch (IllegalArgumentException e) {
1544 pos.errorIndex = start;
1545 pos.index = oldStart;
1546 return null;
1547 }
1548
1549 return parsedDate;
1550 }
1551
1552 /**
1553 * Private code-size reduction function used by subParse.
1554 * @param text the time text being parsed.
1555 * @param start where to start parsing.
1556 * @param field the date field being parsed.
1557 * @param data the string array to parsed.
1558 * @return the new start position if matching succeeded; a negative number
1559 * indicating matching failure, otherwise.
1560 */
1561 private int matchString(String text, int start, int field, String[] data, CalendarBuilder calb)
1562 {
1563 int i = 0;
1564 int count = data.length;
1565
1566 if (field == Calendar.DAY_OF_WEEK) {
1567 i = 1;
1568 }
1569
|
1 /*
2 * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
1474 default:
1475 // Peek the next pattern to determine if we need to
1476 // obey the number of pattern letters for
1477 // parsing. It's required when parsing contiguous
1478 // digit text (e.g., "20010704") with a pattern which
1479 // has no delimiters between fields, like "yyyyMMdd".
1480 boolean obeyCount = false;
1481
1482 // In Arabic, a minus sign for a negative number is put after
1483 // the number. Even in another locale, a minus sign can be
1484 // put after a number using DateFormat.setNumberFormat().
1485 // If both the minus sign and the field-delimiter are '-',
1486 // subParse() needs to determine whether a '-' after a number
1487 // in the given text is a delimiter or is a minus sign for the
1488 // preceding number. We give subParse() a clue based on the
1489 // information in compiledPattern.
1490 boolean useFollowingMinusSignAsDelimiter = false;
1491
1492 if (i < compiledPattern.length) {
1493 int nextTag = compiledPattern[i] >>> 8;
1494 int nextCount = compiledPattern[i] & 0xff;
1495 obeyCount = shouldObeyCount(nextTag, nextCount);
1496
1497 if (hasFollowingMinusSign &&
1498 (nextTag == TAG_QUOTE_ASCII_CHAR ||
1499 nextTag == TAG_QUOTE_CHARS)) {
1500
1501 if (nextTag != TAG_QUOTE_ASCII_CHAR) {
1502 nextCount = compiledPattern[i+1];
1503 }
1504
1505 if (nextCount == minusSign) {
1506 useFollowingMinusSignAsDelimiter = true;
1507 }
1508 }
1509 }
1510 start = subParse(text, start, tag, count, obeyCount,
1511 ambiguousYear, pos,
1512 useFollowingMinusSignAsDelimiter, calb);
1513 if (start < 0) {
1514 pos.index = oldStart;
1515 return null;
1516 }
1517 }
1518 }
1519
1520 // At this point the fields of Calendar have been set. Calendar
1521 // will fill in default values for missing fields when the time
1522 // is computed.
1523
1524 pos.index = start;
1525
1526 Date parsedDate;
1527 try {
1528 parsedDate = calb.establish(calendar).getTime();
1529 // If the year value is ambiguous,
1530 // then the two-digit year == the default start year
1531 if (ambiguousYear[0]) {
1532 if (parsedDate.before(defaultCenturyStart)) {
1533 parsedDate = calb.addYear(100).establish(calendar).getTime();
1534 }
1535 }
1536 }
1537 // An IllegalArgumentException will be thrown by Calendar.getTime()
1538 // if any fields are out of range, e.g., MONTH == 17.
1539 catch (IllegalArgumentException e) {
1540 pos.errorIndex = start;
1541 pos.index = oldStart;
1542 return null;
1543 }
1544
1545 return parsedDate;
1546 }
1547
1548 /* If the next tag/pattern is a <Numeric_Field> then the parser
1549 * should consider the count of digits while parsing the contigous digits
1550 * for the current tag/pattern
1551 */
1552 private boolean shouldObeyCount(int tag, int count) {
1553 switch (tag) {
1554 case PATTERN_MONTH:
1555 case PATTERN_MONTH_STANDALONE:
1556 return count <= 2;
1557 case PATTERN_YEAR:
1558 case PATTERN_DAY_OF_MONTH:
1559 case PATTERN_HOUR_OF_DAY1:
1560 case PATTERN_HOUR_OF_DAY0:
1561 case PATTERN_MINUTE:
1562 case PATTERN_SECOND:
1563 case PATTERN_MILLISECOND:
1564 case PATTERN_DAY_OF_YEAR:
1565 case PATTERN_DAY_OF_WEEK_IN_MONTH:
1566 case PATTERN_WEEK_OF_YEAR:
1567 case PATTERN_WEEK_OF_MONTH:
1568 case PATTERN_HOUR1:
1569 case PATTERN_HOUR0:
1570 case PATTERN_WEEK_YEAR:
1571 case PATTERN_ISO_DAY_OF_WEEK:
1572 return true;
1573 default:
1574 return false;
1575 }
1576 }
1577
1578 /**
1579 * Private code-size reduction function used by subParse.
1580 * @param text the time text being parsed.
1581 * @param start where to start parsing.
1582 * @param field the date field being parsed.
1583 * @param data the string array to parsed.
1584 * @return the new start position if matching succeeded; a negative number
1585 * indicating matching failure, otherwise.
1586 */
1587 private int matchString(String text, int start, int field, String[] data, CalendarBuilder calb)
1588 {
1589 int i = 0;
1590 int count = data.length;
1591
1592 if (field == Calendar.DAY_OF_WEEK) {
1593 i = 1;
1594 }
1595
|