in trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/DateFormat.js [509:875]
function _subparse(
inString, // the pattern string, such as "yyMMdd"
localeSymbols,
locale,
formatType, // the current format char, such as 'y'
startIndex, // index into inString
charCount, // the number of chars of type formatType
parseContext, // information pertaining to the user input string
parsedTime
)
{
// Start index of the string being parsed (as opposed
// to startIndex, which is the index on the format mask)
var inStartIndex = parseContext.currIndex;
var nextFormatType = (startIndex + charCount < inString.length) ?
inString.charAt(startIndex + charCount) : null;
// Consider the pattern "yyMMdd". Say that formatType is 'y' and nextFormatType is 'M'. Normally
// we would allow for leniency such that the user could input 2 or 4 digits for the year, but
// since this pattern contains no date separators and both the year and month can consist of
// digits, there's no easy way of telling whether the first 4 digits apply to just the year, or
// to both the year and month. Therefore, if nextFormatType is one of the reserved format types,
// then we go into strict parsing mode for formatType, where charCount represents the maximum
// number of user input characters that will be parsed when matching the current formatType.
var isStrict = ("DFMSWdhkHKmswy".indexOf(nextFormatType) != -1);
if ((formatType >= 'A') && (formatType <= 'Z') ||
(formatType >= 'a') && (formatType <= 'z'))
{
switch (formatType)
{
case 'D': // day in year
var dayOfYear = _accumulateNumber(parseContext, !isStrict ? 3 : charCount);
if (dayOfYear == null)
return false;
else
parseContext.parsedDayOfYear = dayOfYear;
break;
case 'E': // day in week
{
// extract the day but do nothing with it, as there is not setDay()
// on Date
var dayIndex = _matchArray(parseContext,
(charCount <= 3)
? localeSymbols.getShortWeekdays()
: localeSymbols.getWeekdays());
if (dayIndex == null)
{
return false;
}
}
break;
case 'F': // day of week in month
// skip this number
if (_accumulateNumber(parseContext, !isStrict ? 2 : charCount) == null)
{
return false;
}
break;
case 'G': // era designator
{
var eraIndex = _matchArray(parseContext, localeSymbols.getEras());
if (eraIndex != null)
{
if (eraIndex == 0)
{
parseContext.parsedBC = true;
}
}
else
{
return false;
}
}
break;
case 'M': // month in year
{
var monthIndex;
var monthOffset = 0;
if (charCount <= 2)
{
// match month number
monthIndex = _accumulateNumber(parseContext, !isStrict ? 2 : charCount);
// subtract 1 from the monthIndex to make it 0-based
monthOffset = -1;
}
else
{
var nameArray = (charCount == 3)
? localeSymbols.getShortMonths()
: localeSymbols.getMonths();
monthIndex = _matchArray(parseContext, nameArray);
}
if (monthIndex != null)
{
parseContext.parsedMonth = (monthIndex + monthOffset);
}
else
{
return false;
}
}
break;
case 'S': // millisecond (0 - 999)
{
var milliseconds = _accumulateNumber(parseContext, !isStrict ? 3 : charCount);
if (milliseconds != null)
{
parseContext.parsedMilliseconds = milliseconds;
}
else
{
return false;
}
}
break;
case 'W': // week in month
// skip this number
if (_accumulateNumber(parseContext, !isStrict ? 2 : charCount) == null)
{
return false;
}
break;
case 'a': // am/pm marker
{
var amPMIndex = _matchArray(parseContext,
localeSymbols.getAmPmStrings());
if (amPMIndex == null)
{
return false;
}
else
{
if (amPMIndex == 1)
{
parseContext.isPM = true;
}
}
}
break;
case 'd': // day in month
{
var dayOfMonth = _accumulateNumber(parseContext, !isStrict ? 2 : charCount);
if (dayOfMonth != null)
{
parseContext.parsedDate = dayOfMonth;
}
else
{
return false;
}
}
break;
case 'h': // hour in am/pm (1-12)
case 'k': // hour in day (1-24)
case 'H': // hour in day (0-23)
case 'K': // hour in am/pm (0-11)
{
var hour = _accumulateNumber(parseContext, !isStrict ? 2 : charCount);
if (hour != null)
{
if ((formatType == 'h') && (hour == 12))
hour = 0;
if ((formatType == 'k') && (hour == 24))
hour = 0;
parseContext.parsedHour = hour;
}
else
{
return false;
}
}
break;
case 'm': // minute in hour 0 - 59)
{
var minutes = _accumulateNumber(parseContext, !isStrict ? 2 : charCount);
if (minutes != null)
{
parseContext.parsedMinutes = minutes;
}
else
{
return false;
}
}
break;
case 's': // seconds in minute 0 - 59)
{
var seconds = _accumulateNumber(parseContext, !isStrict ? 2 : charCount);
if (seconds != null)
{
parseContext.parsedSeconds = seconds;
}
else
{
return false;
}
}
break;
case 'w': // week in year
// skip this number
if (_accumulateNumber(parseContext, !isStrict ? 2 : charCount) == null)
{
return false;
}
break;
case 'y': // year
{
// Trinidad-2386: Javascript accepts up to 6 digit year lengths, use maxLength = 6
var year = _accumulateNumber(parseContext, !isStrict ? 6 : charCount);
var enteredChars = parseContext.currIndex - inStartIndex;
// if we have a 2-digit year, add in the default year
if (year != null)
{
if ((enteredChars > 2) &&
(charCount <= 2) &&
(year <= 999))
{
// Block bonus characters; if they've specified
// a two-year mask, and there's more than two characters,
// there might be a problem. But allow four digits.
return false;
}
else if ((charCount <= 2) && (year >= 0) && (year <= 100))
{
year = _fix2DYear(year, locale);
}
else if (charCount == 4)
{
if (enteredChars <= 2)
year = _fix2DYear(year);
}
// There is no year "0"
if (year == 0)
return false;
// Trinidad-2013: Thai Buddhist Calendar is offset by 543 years
if (locale == "th_TH")
year -= _THAI_BUDDHIST_YEAR_OFFSET;
parseContext.parsedFullYear = year;
}
else
{
return false;
}
}
break;
case 'z': // GMT timezone - "GMT Sign Hours : Minutes"
{
// consume the GMT portion
if (!_matchText(parseContext, "GMT"))
{
// GMT is must for timeZone entry.
return false;
}
// if we have any more chars then parse the remaining "+HH:mm" string.
if( (parseContext.parseString.length - parseContext.currIndex) > 0)
{
// consume the plus or minus
if(_matchArray(parseContext, ["-", "+"]) == null)
{
return false;
}
// accumulate the hour offset number
var hourOffset = _accumulateNumber(parseContext, 2);
if(hourOffset == null)
{
return false;
}
parseContext.hourOffset = hourOffset;
// consume the separator between HH and mm
if (!_matchText(parseContext, ":"))
{
return false;
}
// accumulate minute offset number (should have 2 digits)
var minOffset;
if(((parseContext.parseString.length - parseContext.currIndex) < 2) ||
(minOffset = _accumulateNumber(parseContext, 2)) == null)
{
return false;
}
parseContext.minOffset = minOffset;
}
}
break;
case 'Z': // RFC 822 timezone - "Sign TwoDigitHours Minutes"
{
// RFC 822 TimeZone format should have 5 chars (+/-HHmm)
if ((parseContext.parseString.length - parseContext.currIndex) < 5)
{
return false;
}
// consume the plus or minus
if(_matchArray(parseContext, ["-", "+"]) == null)
{
return false;
}
// accumulate the hour offset number
var hourOffset = _accumulateNumber(parseContext, 2)
if(hourOffset == null)
{
return false;
}
parseContext.hourOffset = hourOffset;
// accumulate the minute offset number
var minOffset = _accumulateNumber(parseContext, 2)
if(minOffset == null)
{
return false;
}
parseContext.minOffset = null;
}
break;
default:
}
}
else
{
// consume constants
return _matchText(parseContext,
inString.substring(startIndex, startIndex + charCount));
}
// match succeeded
return true;
}