// This function converts Windows date/time pattern format [1][2] into LDML date // format pattern [3]. // // i.e. // We set h, H, m, s, d, dd, M, or y as is. They have same meaning in both of // Windows and LDML. // We need to convert the following patterns: // t -> a // tt -> a // ddd -> EEE // dddd -> EEEE // g -> G // gg -> ignore // // [1] http://msdn.microsoft.com/en-us/library/dd317787(v=vs.85).aspx // [2] http://msdn.microsoft.com/en-us/library/dd318148(v=vs.85).aspx // [3] LDML http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns static String convertWindowsDateTimeFormat(const String& format) { StringBuilder converted; StringBuilder literalBuffer; bool inQuote = false; bool lastQuoteCanBeLiteral = false; for (unsigned i = 0; i < format.length(); ++i) { UChar ch = format[i]; if (inQuote) { if (ch == '\'') { inQuote = false; ASSERT(i); if (lastQuoteCanBeLiteral && format[i - 1] == '\'') { literalBuffer.append('\''); lastQuoteCanBeLiteral = false; } else lastQuoteCanBeLiteral = true; } else literalBuffer.append(ch); continue; } if (ch == '\'') { inQuote = true; if (lastQuoteCanBeLiteral && i > 0 && format[i - 1] == '\'') { literalBuffer.append(ch); lastQuoteCanBeLiteral = false; } else lastQuoteCanBeLiteral = true; } else if (isASCIIAlpha(ch)) { commitLiteralToken(literalBuffer, converted); unsigned symbolStart = i; unsigned count = countContinuousLetters(format, i); i += count - 1; if (ch == 'h' || ch == 'H' || ch == 'm' || ch == 's' || ch == 'M' || ch == 'y') converted.append(format, symbolStart, count); else if (ch == 'd') { if (count <= 2) converted.append(format, symbolStart, count); else if (count == 3) converted.append("EEE"); else converted.append("EEEE"); } else if (ch == 'g') { if (count == 1) converted.append('G'); else { // gg means imperial era in Windows. // Just ignore it. } } else if (ch == 't') converted.append('a'); else literalBuffer.append(format, symbolStart, count); } else literalBuffer.append(ch); } commitLiteralToken(literalBuffer, converted); return converted.toString(); }
// See http://msdn.microsoft.com/en-us/library/dd317787(v=vs.85).aspx static Vector<DateFormatToken> parseDateFormat(const String format) { Vector<DateFormatToken> tokens; StringBuilder literalBuffer; bool inQuote = false; for (unsigned i = 0; i < format.length(); ++i) { UChar ch = format[i]; if (inQuote) { if (ch == '\'') { inQuote = false; ASSERT(i); if (format[i - 1] == '\'') literalBuffer.append('\''); } else literalBuffer.append(ch); continue; } if (ch == '\'') { inQuote = true; if (i > 0 && format[i - 1] == '\'') literalBuffer.append(ch); } else if (isYearSymbol(ch)) { commitLiteralToken(literalBuffer, tokens); unsigned count = countContinuousLetters(format, i); i += count - 1; if (count == 1) tokens.append(DateFormatToken(DateFormatToken::Year1)); else if (count == 2) tokens.append(DateFormatToken(DateFormatToken::Year2)); else tokens.append(DateFormatToken(DateFormatToken::Year4)); } else if (isMonthSymbol(ch)) { commitLiteralToken(literalBuffer, tokens); unsigned count = countContinuousLetters(format, i); i += count - 1; if (count == 1) tokens.append(DateFormatToken(DateFormatToken::Month1)); else if (count == 2) tokens.append(DateFormatToken(DateFormatToken::Month2)); else if (count == 3) tokens.append(DateFormatToken(DateFormatToken::Month3)); else tokens.append(DateFormatToken(DateFormatToken::Month4)); } else if (isDaySymbol(ch)) { commitLiteralToken(literalBuffer, tokens); unsigned count = countContinuousLetters(format, i); i += count - 1; if (count == 1) tokens.append(DateFormatToken(DateFormatToken::Day1)); else tokens.append(DateFormatToken(DateFormatToken::Day2)); } else if (isEraSymbol(ch)) { // Just ignore era. // HTML5 date supports only A.D. } else literalBuffer.append(ch); } commitLiteralToken(literalBuffer, tokens); return tokens; }