diff options
Diffstat (limited to 'src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs')
-rw-r--r-- | src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs | 249 |
1 files changed, 125 insertions, 124 deletions
diff --git a/src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs b/src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs index 4555bb2463..630d345cd9 100644 --- a/src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs +++ b/src/mscorlib/src/System/Globalization/DateTimeFormatInfoScanner.cs @@ -18,7 +18,7 @@ // //////////////////////////////////////////////////////////////////////////// -namespace System.Globalization +namespace System.Globalization { using System; using System.Globalization; @@ -31,14 +31,15 @@ namespace System.Globalization // //; IFORMATFLAGS //; Parsing/formatting flags. - internal enum FORMATFLAGS { - None = 0x00000000, - UseGenitiveMonth = 0x00000001, - UseLeapYearMonth = 0x00000002, - UseSpacesInMonthNames = 0x00000004, - UseHebrewParsing = 0x00000008, - UseSpacesInDayNames = 0x00000010, // Has spaces or non-breaking space in the day names. - UseDigitPrefixInTokens = 0x00000020, // Has token starting with numbers. + internal enum FORMATFLAGS + { + None = 0x00000000, + UseGenitiveMonth = 0x00000001, + UseLeapYearMonth = 0x00000002, + UseSpacesInMonthNames = 0x00000004, + UseHebrewParsing = 0x00000008, + UseSpacesInDayNames = 0x00000010, // Has spaces or non-breaking space in the day names. + UseDigitPrefixInTokens = 0x00000020, // Has token starting with numbers. } // @@ -48,37 +49,38 @@ namespace System.Globalization internal enum CalendarId : ushort { - GREGORIAN = 1 , // Gregorian (localized) calendar - GREGORIAN_US = 2 , // Gregorian (U.S.) calendar - JAPAN = 3 , // Japanese Emperor Era calendar -/* SSS_WARNINGS_OFF */ TAIWAN = 4 , // Taiwan Era calendar /* SSS_WARNINGS_ON */ - KOREA = 5 , // Korean Tangun Era calendar - HIJRI = 6 , // Hijri (Arabic Lunar) calendar - THAI = 7 , // Thai calendar - HEBREW = 8 , // Hebrew (Lunar) calendar - GREGORIAN_ME_FRENCH = 9 , // Gregorian Middle East French calendar - GREGORIAN_ARABIC = 10, // Gregorian Arabic calendar - GREGORIAN_XLIT_ENGLISH = 11, // Gregorian Transliterated English calendar - GREGORIAN_XLIT_FRENCH = 12, -// Note that all calendars after this point are MANAGED ONLY for now. - JULIAN = 13, - JAPANESELUNISOLAR = 14, - CHINESELUNISOLAR = 15, - SAKA = 16, // reserved to match Office but not implemented in our code - LUNAR_ETO_CHN = 17, // reserved to match Office but not implemented in our code - LUNAR_ETO_KOR = 18, // reserved to match Office but not implemented in our code - LUNAR_ETO_ROKUYOU = 19, // reserved to match Office but not implemented in our code - KOREANLUNISOLAR = 20, - TAIWANLUNISOLAR = 21, - PERSIAN = 22, - UMALQURA = 23, - LAST_CALENDAR = 23 // Last calendar ID + GREGORIAN = 1, // Gregorian (localized) calendar + GREGORIAN_US = 2, // Gregorian (U.S.) calendar + JAPAN = 3, // Japanese Emperor Era calendar + /* SSS_WARNINGS_OFF */ + TAIWAN = 4, // Taiwan Era calendar /* SSS_WARNINGS_ON */ + KOREA = 5, // Korean Tangun Era calendar + HIJRI = 6, // Hijri (Arabic Lunar) calendar + THAI = 7, // Thai calendar + HEBREW = 8, // Hebrew (Lunar) calendar + GREGORIAN_ME_FRENCH = 9, // Gregorian Middle East French calendar + GREGORIAN_ARABIC = 10, // Gregorian Arabic calendar + GREGORIAN_XLIT_ENGLISH = 11, // Gregorian Transliterated English calendar + GREGORIAN_XLIT_FRENCH = 12, + // Note that all calendars after this point are MANAGED ONLY for now. + JULIAN = 13, + JAPANESELUNISOLAR = 14, + CHINESELUNISOLAR = 15, + SAKA = 16, // reserved to match Office but not implemented in our code + LUNAR_ETO_CHN = 17, // reserved to match Office but not implemented in our code + LUNAR_ETO_KOR = 18, // reserved to match Office but not implemented in our code + LUNAR_ETO_ROKUYOU = 19, // reserved to match Office but not implemented in our code + KOREANLUNISOLAR = 20, + TAIWANLUNISOLAR = 21, + PERSIAN = 22, + UMALQURA = 23, + LAST_CALENDAR = 23 // Last calendar ID } - + internal class DateTimeFormatInfoScanner { // Special prefix-like flag char in DateWord array. - + // Use char in PUA area since we won't be using them in real data. // The char used to tell a read date word or a month postfix. A month postfix // is "ta" in the long date pattern like "d. MMMM'ta 'yyyy" for fi-FI. @@ -86,7 +88,7 @@ namespace System.Globalization internal const char MonthPostfixChar = '\xe000'; // Add ignorable symbol in a DateWord array. - + // hu-HU has: // shrot date pattern: yyyy. MM. dd.;yyyy-MM-dd;yy-MM-dd // long date pattern: yyyy. MMMM d. @@ -95,33 +97,33 @@ namespace System.Globalization // "." as ignorable symbol so that the DateTime.Parse() state machine will not // treat the additional date separator at the end of y,m,d pattern as an error // condition. - internal const char IgnorableSymbolChar = '\xe001'; + internal const char IgnorableSymbolChar = '\xe001'; // Known CJK suffix - internal const String CJKYearSuff = "\u5e74"; - internal const String CJKMonthSuff = "\u6708"; - internal const String CJKDaySuff = "\u65e5"; + internal const String CJKYearSuff = "\u5e74"; + internal const String CJKMonthSuff = "\u6708"; + internal const String CJKDaySuff = "\u65e5"; - internal const String KoreanYearSuff = "\ub144"; - internal const String KoreanMonthSuff = "\uc6d4"; - internal const String KoreanDaySuff = "\uc77c"; + internal const String KoreanYearSuff = "\ub144"; + internal const String KoreanMonthSuff = "\uc6d4"; + internal const String KoreanDaySuff = "\uc77c"; - internal const String KoreanHourSuff = "\uc2dc"; - internal const String KoreanMinuteSuff = "\ubd84"; - internal const String KoreanSecondSuff = "\ucd08"; + internal const String KoreanHourSuff = "\uc2dc"; + internal const String KoreanMinuteSuff = "\ubd84"; + internal const String KoreanSecondSuff = "\ucd08"; - internal const String CJKHourSuff = "\u6642"; - internal const String ChineseHourSuff = "\u65f6"; + internal const String CJKHourSuff = "\u6642"; + internal const String ChineseHourSuff = "\u65f6"; - internal const String CJKMinuteSuff = "\u5206"; - internal const String CJKSecondSuff = "\u79d2"; + internal const String CJKMinuteSuff = "\u5206"; + internal const String CJKSecondSuff = "\u79d2"; // The collection fo date words & postfix. internal List<String> m_dateWords = new List<String>(); // Hashtable for the known words. private static volatile Dictionary<String, String> s_knownWords; - static Dictionary<String, String> KnownWords + private static Dictionary<String, String> KnownWords { get { @@ -186,14 +188,15 @@ namespace System.Globalization continue; } // Fall thru to check if this is a letter. - } else + } + else { // End of string break; } } if (Char.IsLetter(ch) || ch == '\'' || ch == '.') - { + { break; } // Skip the current char since it is not a letter. @@ -239,7 +242,8 @@ namespace System.Globalization { m_dateWords.Add(temp); } - } else + } + else { if (!m_dateWords.Contains(str)) { @@ -251,14 +255,12 @@ namespace System.Globalization String strWithoutDot = str.Substring(0, str.Length - 1); if (!m_dateWords.Contains(strWithoutDot)) { - m_dateWords.Add(strWithoutDot); + m_dateWords.Add(strWithoutDot); } - } } } } - } //////////////////////////////////////////////////////////////////////////// @@ -283,18 +285,18 @@ namespace System.Globalization if (newIndex != index && formatPostfix != null) { // There are whitespaces. This will not be a postfix. - formatPostfix = null; + formatPostfix = null; } index = newIndex; // This is the first char added into dateWord. // Skip all non-letter character. We will add the first letter into DateWord. - StringBuilder dateWord = new StringBuilder(); + StringBuilder dateWord = new StringBuilder(); // We assume that date words should start with a letter. // Skip anything until we see a letter. - + while (index < pattern.Length) - { + { char ch = pattern[index]; if (ch == '\'') { @@ -303,12 +305,13 @@ namespace System.Globalization AddDateWordOrPostfix(formatPostfix, dateWord.ToString()); index++; break; - } else if (ch == '\\') + } + else if (ch == '\\') { // // Escaped character. Look ahead one character // - + // Skip escaped backslash. index++; if (index < pattern.Length) @@ -316,7 +319,8 @@ namespace System.Globalization dateWord.Append(pattern[index]); index++; } - } else if (Char.IsWhiteSpace(ch)) + } + else if (Char.IsWhiteSpace(ch)) { // Found a whitespace. We have to add the current date word/postfix. AddDateWordOrPostfix(formatPostfix, dateWord.ToString()); @@ -328,12 +332,13 @@ namespace System.Globalization // Reset the dateWord. dateWord.Length = 0; index++; - } else + } + else { - dateWord.Append(ch); + dateWord.Append(ch); index++; } - } + } return (index); } @@ -345,11 +350,12 @@ namespace System.Globalization internal static int ScanRepeatChar(String pattern, char ch, int index, out int count) { count = 1; - while (++index < pattern.Length && pattern[index] == ch) { + while (++index < pattern.Length && pattern[index] == ch) + { count++; } // Return the updated position. - return (index); + return (index); } //////////////////////////////////////////////////////////////////////////// @@ -366,7 +372,7 @@ namespace System.Globalization // condition. // //////////////////////////////////////////////////////////////////////////// - + internal void AddIgnorableSymbols(String text) { if (m_dateWords == null) @@ -386,17 +392,17 @@ namespace System.Globalization // // Flag used to trace the date patterns (yy/yyyyy/M/MM/MMM/MMM/d/dd) that we have seen. // - enum FoundDatePattern + private enum FoundDatePattern { - None = 0x0000, - FoundYearPatternFlag = 0x0001, + None = 0x0000, + FoundYearPatternFlag = 0x0001, FoundMonthPatternFlag = 0x0002, - FoundDayPatternFlag = 0x0004, - FoundYMDPatternFlag = 0x0007, // FoundYearPatternFlag | FoundMonthPatternFlag | FoundDayPatternFlag; + FoundDayPatternFlag = 0x0004, + FoundYMDPatternFlag = 0x0007, // FoundYearPatternFlag | FoundMonthPatternFlag | FoundDayPatternFlag; } // Check if we have found all of the year/month/day pattern. - FoundDatePattern m_ymdFlags = FoundDatePattern.None; + private FoundDatePattern m_ymdFlags = FoundDatePattern.None; //////////////////////////////////////////////////////////////////////////// @@ -423,21 +429,20 @@ namespace System.Globalization //////////////////////////////////////////////////////////////////////////// internal void ScanDateWord(String pattern) { - // Check if we have found all of the year/month/day pattern. m_ymdFlags = FoundDatePattern.None; - + int i = 0; while (i < pattern.Length) { - char ch = pattern[i]; + char ch = pattern[i]; int chCount; - + switch (ch) { case '\'': // Find a beginning quote. Search until the end quote. - i = AddDateWords(pattern, i+1, null); + i = AddDateWords(pattern, i + 1, null); break; case 'M': i = ScanRepeatChar(pattern, 'M', i, out chCount); @@ -445,7 +450,7 @@ namespace System.Globalization { if (i < pattern.Length && pattern[i] == '\'') { - i = AddDateWords(pattern, i+1, "MMMM"); + i = AddDateWords(pattern, i + 1, "MMMM"); } } m_ymdFlags |= FoundDatePattern.FoundMonthPatternFlag; @@ -488,8 +493,8 @@ namespace System.Globalization // We are not in quote. Skip the current character. i++; break; - } - } + } + } } //////////////////////////////////////////////////////////////////////////// @@ -497,17 +502,18 @@ namespace System.Globalization // Given a DTFI, get all of the date words from date patterns and time patterns. // //////////////////////////////////////////////////////////////////////////// - - internal String[] GetDateWordsOfDTFI(DateTimeFormatInfo dtfi) { + + internal String[] GetDateWordsOfDTFI(DateTimeFormatInfo dtfi) + { // Enumarate all LongDatePatterns, and get the DateWords and scan for month postfix. String[] datePatterns = dtfi.GetAllDateTimePatterns('D'); int i; - + // Scan the long date patterns for (i = 0; i < datePatterns.Length; i++) { ScanDateWord(datePatterns[i]); - } + } // Scan the short date patterns datePatterns = dtfi.GetAllDateTimePatterns('d'); @@ -520,24 +526,24 @@ namespace System.Globalization for (i = 0; i < datePatterns.Length; i++) { ScanDateWord(datePatterns[i]); - } + } // Scan the month/day pattern ScanDateWord(dtfi.MonthDayPattern); - + // Scan the long time patterns. datePatterns = dtfi.GetAllDateTimePatterns('T'); for (i = 0; i < datePatterns.Length; i++) { ScanDateWord(datePatterns[i]); - } + } // Scan the short time patterns. datePatterns = dtfi.GetAllDateTimePatterns('t'); for (i = 0; i < datePatterns.Length; i++) { ScanDateWord(datePatterns[i]); - } + } String[] result = null; if (m_dateWords != null && m_dateWords.Count > 0) @@ -574,7 +580,7 @@ namespace System.Globalization { // If we have different names in regular and genitive month names, use genitive month flag. return ((!EqualStringArrays(monthNames, genitveMonthNames) || !EqualStringArrays(abbrevMonthNames, genetiveAbbrevMonthNames)) - ? FORMATFLAGS.UseGenitiveMonth: 0); + ? FORMATFLAGS.UseGenitiveMonth : 0); } //////////////////////////////////////////////////////////////////////////// @@ -585,16 +591,16 @@ namespace System.Globalization internal static FORMATFLAGS GetFormatFlagUseSpaceInMonthNames(String[] monthNames, String[] genitveMonthNames, String[] abbrevMonthNames, String[] genetiveAbbrevMonthNames) { FORMATFLAGS formatFlags = 0; - formatFlags |= (ArrayElementsBeginWithDigit(monthNames) || - ArrayElementsBeginWithDigit(genitveMonthNames) || - ArrayElementsBeginWithDigit(abbrevMonthNames) || - ArrayElementsBeginWithDigit(genetiveAbbrevMonthNames) + formatFlags |= (ArrayElementsBeginWithDigit(monthNames) || + ArrayElementsBeginWithDigit(genitveMonthNames) || + ArrayElementsBeginWithDigit(abbrevMonthNames) || + ArrayElementsBeginWithDigit(genetiveAbbrevMonthNames) ? FORMATFLAGS.UseDigitPrefixInTokens : 0); - formatFlags |= (ArrayElementsHaveSpace(monthNames) || - ArrayElementsHaveSpace(genitveMonthNames) || - ArrayElementsHaveSpace(abbrevMonthNames) || - ArrayElementsHaveSpace(genetiveAbbrevMonthNames) + formatFlags |= (ArrayElementsHaveSpace(monthNames) || + ArrayElementsHaveSpace(genitveMonthNames) || + ArrayElementsHaveSpace(abbrevMonthNames) || + ArrayElementsHaveSpace(genetiveAbbrevMonthNames) ? FORMATFLAGS.UseSpacesInMonthNames : 0); return (formatFlags); } @@ -606,10 +612,9 @@ namespace System.Globalization //////////////////////////////////////////////////////////////////////////// internal static FORMATFLAGS GetFormatFlagUseSpaceInDayNames(String[] dayNames, String[] abbrevDayNames) { - return ((ArrayElementsHaveSpace(dayNames) || - ArrayElementsHaveSpace(abbrevDayNames)) + return ((ArrayElementsHaveSpace(dayNames) || + ArrayElementsHaveSpace(abbrevDayNames)) ? FORMATFLAGS.UseSpacesInDayNames : 0); - } //////////////////////////////////////////////////////////////////////////// @@ -630,8 +635,8 @@ namespace System.Globalization // array equals to all elmentsof the second array. // otherwise it returns false. //----------------------------------------------------------------------------- - - private static bool EqualStringArrays(string [] array1, string [] array2) + + private static bool EqualStringArrays(string[] array1, string[] array2) { // Shortcut if they're the same array if (array1 == array2) @@ -646,7 +651,7 @@ namespace System.Globalization } // Check each string - for (int i=0; i<array1.Length; i++) + for (int i = 0; i < array1.Length; i++) { if (!array1[i].Equals(array2[i])) { @@ -663,17 +668,16 @@ namespace System.Globalization // returns true if found space character in one of the array elements. // otherwise returns false. //----------------------------------------------------------------------------- - - private static bool ArrayElementsHaveSpace(string [] array) - { - for (int i=0; i<array.Length; i++) + private static bool ArrayElementsHaveSpace(string[] array) + { + for (int i = 0; i < array.Length; i++) { // it is faster to check for space character manually instead of calling IndexOf // so we don't have to go to native code side. - for (int j=0; j<array[i].Length; j++) + for (int j = 0; j < array[i].Length; j++) { - if ( Char.IsWhiteSpace(array[i][j]) ) + if (Char.IsWhiteSpace(array[i][j])) { return true; } @@ -681,7 +685,7 @@ namespace System.Globalization } return false; - } + } //////////////////////////////////////////////////////////////////////////// @@ -689,10 +693,9 @@ namespace System.Globalization // Check if any element of the array start with a digit. // //////////////////////////////////////////////////////////////////////////// - private static bool ArrayElementsBeginWithDigit(string [] array) + private static bool ArrayElementsBeginWithDigit(string[] array) { - - for (int i=0; i<array.Length; i++) + for (int i = 0; i < array.Length; i++) { // it is faster to check for space character manually instead of calling IndexOf // so we don't have to go to native code side. @@ -707,7 +710,7 @@ namespace System.Globalization } if (index == array[i].Length) { - return (false); + return (false); } if (index == array[i].Length - 1) @@ -728,20 +731,18 @@ namespace System.Globalization // Skip known CJK month suffix. // Starting with Windows 8, the CJK months for some cultures looks like: "1' \x6708'" // instead of just "1\x6708" - if(array[i][index] == '\'' && array[i][index + 1] == ' ' && + if (array[i][index] == '\'' && array[i][index + 1] == ' ' && array[i][index + 2] == '\x6708' && array[i][index + 3] == '\'') { return (false); } - } return (true); } } return false; - } - + } } -} +} |