private static synchronized void initCache() { if (CACHE.size() <= 0) { for (FormatTokenEnum token : FormatTokenEnum.values()) { List<Character> tokenKeys = new ArrayList<Character>(); if (token.name().contains("_")) { String[] tokens = token.name().split("_"); for (String tokenLets : tokens) { tokenKeys.add(tokenLets.toUpperCase().charAt(0)); } } else { tokenKeys.add(token.name().toUpperCase().charAt(0)); } for (Character tokenKey : tokenKeys) { List<FormatTokenEnum> l = CACHE.get(tokenKey); if (l == null) { l = new ArrayList<FormatTokenEnum>(1); CACHE.put(tokenKey, l); } l.add(token); } } } }
@Override public void parse(ToDateParser params, FormatTokenEnum formatTokenEnum, String formatTokenStr) { Calendar result = params.getResultCalendar(); String s = params.getInputStr(); String inputFragmentStr = null; int dateNr = 0; switch (formatTokenEnum) { case MONTH: inputFragmentStr = setByName(result, params, Calendar.MONTH, Calendar.LONG); break; case Q /*NOT supported yet*/: throwException(params, format("token '%s' not supported yet.", formatTokenEnum.name())); break; case MON: inputFragmentStr = setByName(result, params, Calendar.MONTH, Calendar.SHORT); break; case MM: // Note: In Calendar Month go from 0 - 11 inputFragmentStr = matchStringOrThrow(PATTERN_TWO_DIGITS_OR_LESS, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr); result.set(Calendar.MONTH, dateNr - 1); break; case RM: dateNr = 0; for (String monthName : ROMAN_MONTH) { dateNr++; int len = monthName.length(); if (s.length() >= len && monthName.equalsIgnoreCase(s.substring(0, len))) { result.set(Calendar.MONTH, dateNr); inputFragmentStr = monthName; break; } } if (inputFragmentStr == null || inputFragmentStr.isEmpty()) { throwException( params, format( "Issue happened when parsing token '%s'. " + "Expected one of: %s", formatTokenEnum.name(), Arrays.toString(ROMAN_MONTH))); } break; default: throw new IllegalArgumentException( format( "%s: Internal Error. Unhandled case: %s", this.getClass().getSimpleName(), formatTokenEnum)); } params.remove(inputFragmentStr, formatTokenStr); }
@Override public void parse(ToDateParser params, FormatTokenEnum formatTokenEnum, String formatTokenStr) { Calendar result = params.getResultCalendar(); String inputFragmentStr = null; int dateNr = 0; switch (formatTokenEnum) { case SYYYY: case YYYY: case IYYY: inputFragmentStr = matchStringOrThrow(PATTERN_FOUR_DIGITS, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr); // Gregorian calendar does not have a year 0. // 0 = 0001 BC, -1 = 0002 BC, ... so we adjust result.set(Calendar.YEAR, dateNr >= 0 ? dateNr : dateNr + 1); break; case YYY: case IYY: inputFragmentStr = matchStringOrThrow(PATTERN_THREE_DIGITS, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr); // Gregorian calendar does not have a year 0. // 0 = 0001 BC, -1 = 0002 BC, ... so we adjust result.set(Calendar.YEAR, dateNr >= 0 ? dateNr : dateNr + 1); break; case RRRR: inputFragmentStr = matchStringOrThrow(PATTERN_TWO_DIGITS, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr); dateNr += dateNr < 50 ? 2000 : 1900; result.set(Calendar.YEAR, dateNr); break; case RR: Calendar calendar = Calendar.getInstance(); int cc = calendar.get(Calendar.YEAR) / 100; inputFragmentStr = matchStringOrThrow(PATTERN_TWO_DIGITS, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr) + cc * 100; result.set(Calendar.YEAR, dateNr); break; case EE /*NOT supported yet*/: throwException(params, format("token '%s' not supported yet.", formatTokenEnum.name())); break; case E /*NOT supported yet*/: throwException(params, format("token '%s' not supported yet.", formatTokenEnum.name())); break; case YY: case IY: inputFragmentStr = matchStringOrThrow(PATTERN_TWO_DIGITS, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr); // Gregorian calendar does not have a year 0. // 0 = 0001 BC, -1 = 0002 BC, ... so we adjust result.set(Calendar.YEAR, dateNr >= 0 ? dateNr : dateNr + 1); break; case SCC: case CC: inputFragmentStr = matchStringOrThrow(PATTERN_TWO_DIGITS, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr) * 100; result.set(Calendar.YEAR, dateNr); break; case Y: case I: inputFragmentStr = matchStringOrThrow(PATTERN_ONE_DIGIT, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr); // Gregorian calendar does not have a year 0. // 0 = 0001 BC, -1 = 0002 BC, ... so we adjust result.set(Calendar.YEAR, dateNr >= 0 ? dateNr : dateNr + 1); break; case BC_AD: inputFragmentStr = matchStringOrThrow(PATTERN_BC_AD, params, formatTokenEnum); if (inputFragmentStr.toUpperCase().startsWith("B")) { result.set(Calendar.ERA, GregorianCalendar.BC); } else { result.set(Calendar.ERA, GregorianCalendar.AD); } break; default: throw new IllegalArgumentException( format( "%s: Internal Error. Unhandled case: %s", this.getClass().getSimpleName(), formatTokenEnum)); } params.remove(inputFragmentStr, formatTokenStr); }
@Override public void parse(ToDateParser params, FormatTokenEnum formatTokenEnum, String formatTokenStr) { Calendar result = params.getResultCalendar(); String inputFragmentStr = null; int dateNr = 0; switch (formatTokenEnum) { case HH24: inputFragmentStr = matchStringOrThrow(PATTERN_TWO_DIGITS_OR_LESS, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr); result.set(Calendar.HOUR_OF_DAY, dateNr); break; case HH12: case HH: inputFragmentStr = matchStringOrThrow(PATTERN_TWO_DIGITS_OR_LESS, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr); result.set(Calendar.HOUR, dateNr); break; case MI: inputFragmentStr = matchStringOrThrow(PATTERN_TWO_DIGITS_OR_LESS, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr); result.set(Calendar.MINUTE, dateNr); break; case SS: inputFragmentStr = matchStringOrThrow(PATTERN_TWO_DIGITS_OR_LESS, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr); result.set(Calendar.SECOND, dateNr); break; case SSSSS: inputFragmentStr = matchStringOrThrow(PATTERN_NUMBER, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr); result.set(Calendar.HOUR_OF_DAY, 0); result.set(Calendar.MINUTE, 0); result.set(Calendar.SECOND, dateNr); break; case FF: inputFragmentStr = matchStringOrThrow(PATTERN_NUMBER, params, formatTokenEnum); String paddedRightNrStr = format("%-9s", inputFragmentStr).replace(' ', '0'); paddedRightNrStr = paddedRightNrStr.substring(0, 9); Double nineDigits = Double.parseDouble(paddedRightNrStr); params.setNanos(nineDigits.intValue()); dateNr = (int) Math.round(nineDigits / 1000000.0); result.set(Calendar.MILLISECOND, dateNr); break; case AM_PM: inputFragmentStr = matchStringOrThrow(PATTERN_AM_PM, params, formatTokenEnum); if (inputFragmentStr.toUpperCase().startsWith("A")) { result.set(Calendar.AM_PM, Calendar.AM); } else { result.set(Calendar.AM_PM, Calendar.PM); } break; case TZH: inputFragmentStr = matchStringOrThrow(PATTERN_TWO_DIGITS_OR_LESS, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr); TimeZone tz = result.getTimeZone(); int offsetMillis = tz.getRawOffset(); // purge min and sec offsetMillis = (offsetMillis / MILLIS_IN_HOUR) * MILLIS_IN_HOUR; tz.setRawOffset(offsetMillis + dateNr); result.setTimeZone(tz); break; case TZM: inputFragmentStr = matchStringOrThrow(PATTERN_TWO_DIGITS_OR_LESS, params, formatTokenEnum); dateNr = parseInt(inputFragmentStr); tz = result.getTimeZone(); offsetMillis = tz.getRawOffset(); // purge hour offsetMillis = offsetMillis % MILLIS_IN_HOUR; tz.setRawOffset(dateNr * MILLIS_IN_HOUR + offsetMillis); result.setTimeZone(tz); break; case TZR: // Example: US/Pacific String s = params.getInputStr(); tz = result.getTimeZone(); for (String tzName : TimeZone.getAvailableIDs()) { int length = tzName.length(); if (s.length() >= length && tzName.equalsIgnoreCase(s.substring(0, length))) { tz.setID(tzName); result.setTimeZone(tz); inputFragmentStr = tzName; break; } } break; case TZD: // Must correspond with TZR region. Example: PST (for US/Pacific // standard time) throwException(params, format("token '%s' not supported yet.", formatTokenEnum.name())); break; default: throw new IllegalArgumentException( format( "%s: Internal Error. Unhandled case: %s", this.getClass().getSimpleName(), formatTokenEnum)); } params.remove(inputFragmentStr, formatTokenStr); }