// // FormatCustomized // // Actions: Format the DateTime instance using the specified format. // private static String FormatCustomized(DateTime dateTime, String format, DateTimeFormatInfo dtfi, TimeSpan offset) { Calendar cal = dtfi.Calendar; StringBuilder result = StringBuilderCache.Acquire(); // This is a flag to indicate if we are format the dates using Hebrew calendar. bool isHebrewCalendar = (cal.ID == Calendar.CAL_HEBREW); // This is a flag to indicate if we are formating hour/minute/second only. bool bTimeOnly = true; int i = 0; int tokenLen, hour12; while (i < format.Length) { char ch = format[i]; int nextChar; switch (ch) { case 'g': tokenLen = ParseRepeatPattern(format, i, ch); result.Append(dtfi.GetEraName(cal.GetEra(dateTime))); break; case 'h': tokenLen = ParseRepeatPattern(format, i, ch); hour12 = dateTime.Hour % 12; if (hour12 == 0) { hour12 = 12; } FormatDigits(result, hour12, tokenLen); break; case 'H': tokenLen = ParseRepeatPattern(format, i, ch); FormatDigits(result, dateTime.Hour, tokenLen); break; case 'm': tokenLen = ParseRepeatPattern(format, i, ch); FormatDigits(result, dateTime.Minute, tokenLen); break; case 's': tokenLen = ParseRepeatPattern(format, i, ch); FormatDigits(result, dateTime.Second, tokenLen); break; case 'f': case 'F': tokenLen = ParseRepeatPattern(format, i, ch); if (tokenLen <= MaxSecondsFractionDigits) { long fraction = (dateTime.Ticks % Calendar.TicksPerSecond); fraction = fraction / (long)Math.Pow(10, 7 - tokenLen); if (ch == 'f') { result.Append(((int)fraction).ToString(fixedNumberFormats[tokenLen - 1], CultureInfo.InvariantCulture)); } else { int effectiveDigits = tokenLen; while (effectiveDigits > 0) { if (fraction % 10 == 0) { fraction = fraction / 10; effectiveDigits--; } else { break; } } if (effectiveDigits > 0) { result.Append(((int)fraction).ToString(fixedNumberFormats[effectiveDigits - 1], CultureInfo.InvariantCulture)); } else { // No fraction to emit, so see if we should remove decimal also. if (result.Length > 0 && result[result.Length - 1] == '.') { result.Remove(result.Length - 1, 1); } } } } else { throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } break; case 't': tokenLen = ParseRepeatPattern(format, i, ch); if (tokenLen == 1) { if (dateTime.Hour < 12) { if (dtfi.AMDesignator.Length >= 1) { result.Append(dtfi.AMDesignator[0]); } } else { if (dtfi.PMDesignator.Length >= 1) { result.Append(dtfi.PMDesignator[0]); } } } else { result.Append((dateTime.Hour < 12 ? dtfi.AMDesignator : dtfi.PMDesignator)); } break; case 'd': // // tokenLen == 1 : Day of month as digits with no leading zero. // tokenLen == 2 : Day of month as digits with leading zero for single-digit months. // tokenLen == 3 : Day of week as a three-leter abbreviation. // tokenLen >= 4 : Day of week as its full name. // tokenLen = ParseRepeatPattern(format, i, ch); if (tokenLen <= 2) { int day = cal.GetDayOfMonth(dateTime); if (isHebrewCalendar) { // For Hebrew calendar, we need to convert numbers to Hebrew text for yyyy, MM, and dd values. HebrewFormatDigits(result, day); } else { FormatDigits(result, day, tokenLen); } } else { int dayOfWeek = (int)cal.GetDayOfWeek(dateTime); result.Append(FormatDayOfWeek(dayOfWeek, tokenLen, dtfi)); } bTimeOnly = false; break; case 'M': // // tokenLen == 1 : Month as digits with no leading zero. // tokenLen == 2 : Month as digits with leading zero for single-digit months. // tokenLen == 3 : Month as a three-letter abbreviation. // tokenLen >= 4 : Month as its full name. // tokenLen = ParseRepeatPattern(format, i, ch); int month = cal.GetMonth(dateTime); if (tokenLen <= 2) { if (isHebrewCalendar) { // For Hebrew calendar, we need to convert numbers to Hebrew text for yyyy, MM, and dd values. HebrewFormatDigits(result, month); } else { FormatDigits(result, month, tokenLen); } } else { if (isHebrewCalendar) { result.Append(FormatHebrewMonthName(dateTime, month, tokenLen, dtfi)); } else { if ((dtfi.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0 && tokenLen >= 4) { result.Append( dtfi.internalGetMonthName( month, IsUseGenitiveForm(format, i, tokenLen, 'd')? MonthNameStyles.Genitive : MonthNameStyles.Regular, false)); } else { result.Append(FormatMonth(month, tokenLen, dtfi)); } } } bTimeOnly = false; break; case 'y': // Notes about OS behavior: // y: Always print (year % 100). No leading zero. // yy: Always print (year % 100) with leading zero. // yyy/yyyy/yyyyy/... : Print year value. No leading zero. int year = cal.GetYear(dateTime); tokenLen = ParseRepeatPattern(format, i, ch); if (dtfi.HasForceTwoDigitYears) { FormatDigits(result, year, tokenLen <= 2 ? tokenLen : 2); } else if (cal.ID == Calendar.CAL_HEBREW) { HebrewFormatDigits(result, year); } else { if (tokenLen <= 2) { FormatDigits(result, year % 100, tokenLen); } else { String fmtPattern = "D" + tokenLen; result.Append(year.ToString(fmtPattern, CultureInfo.InvariantCulture)); } } bTimeOnly = false; break; case 'z': tokenLen = ParseRepeatPattern(format, i, ch); FormatCustomizedTimeZone(dateTime, offset, format, tokenLen, bTimeOnly, result); break; case 'K': tokenLen = 1; FormatCustomizedRoundripTimeZone(dateTime, offset, result); break; case ':': result.Append(dtfi.TimeSeparator); tokenLen = 1; break; case '/': result.Append(dtfi.DateSeparator); tokenLen = 1; break; case '\'': case '\"': StringBuilder enquotedString = new StringBuilder(); tokenLen = ParseQuoteString(format, i, enquotedString); result.Append(enquotedString); break; case '%': // Optional format character. // For example, format string "%d" will print day of month // without leading zero. Most of the cases, "%" can be ignored. nextChar = ParseNextChar(format, i); // nextChar will be -1 if we already reach the end of the format string. // Besides, we will not allow "%%" appear in the pattern. if (nextChar >= 0 && nextChar != (int)'%') { result.Append(FormatCustomized(dateTime, ((char)nextChar).ToString(), dtfi, offset)); tokenLen = 2; } else { // // This means that '%' is at the end of the format string or // "%%" appears in the format string. // throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } break; case '\\': // Escaped character. Can be used to insert character into the format string. // For exmple, "\d" will insert the character 'd' into the string. // // NOTENOTE : we can remove this format character if we enforce the enforced quote // character rule. // That is, we ask everyone to use single quote or double quote to insert characters, // then we can remove this character. // nextChar = ParseNextChar(format, i); if (nextChar >= 0) { result.Append(((char)nextChar)); tokenLen = 2; } else { // // This means that '\' is at the end of the formatting string. // throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } break; default: // NOTENOTE : we can remove this rule if we enforce the enforced quote // character rule. // That is, if we ask everyone to use single quote or double quote to insert characters, // then we can remove this default block. result.Append(ch); tokenLen = 1; break; } i += tokenLen; } return StringBuilderCache.GetStringAndRelease(result); }
// // FormatHebrewMonthName // // Action: Return the Hebrew month name for the specified DateTime. // Returns: The month name string for the specified DateTime. // Arguments: // time the time to format // month The month is the value of HebrewCalendar.GetMonth(time). // repeat Return abbreviated month name if repeat=3, or full month name if repeat=4 // dtfi The DateTimeFormatInfo which uses the Hebrew calendars as its calendar. // Exceptions: None. // /* Note: If DTFI is using Hebrew calendar, GetMonthName()/GetAbbreviatedMonthName() will return month names like this: 1 Hebrew 1st Month 2 Hebrew 2nd Month .. ... 6 Hebrew 6th Month 7 Hebrew 6th Month II (used only in a leap year) 8 Hebrew 7th Month 9 Hebrew 8th Month 10 Hebrew 9th Month 11 Hebrew 10th Month 12 Hebrew 11th Month 13 Hebrew 12th Month Therefore, if we are in a regular year, we have to increment the month name if moth is greater or eqaul to 7. */ private static String FormatHebrewMonthName(DateTime time, int month, int repeatCount, DateTimeFormatInfo dtfi) { Contract.Assert(repeatCount != 3 || repeatCount != 4, "repeateCount should be 3 or 4"); if (dtfi.Calendar.IsLeapYear(dtfi.Calendar.GetYear(time))) { // This month is in a leap year return (dtfi.internalGetMonthName(month, MonthNameStyles.LeapYear, (repeatCount == 3))); } // This is in a regular year. if (month >= 7) { month++; } if (repeatCount == 3) { return (dtfi.GetAbbreviatedMonthName(month)); } return (dtfi.GetMonthName(month)); }
private static string FormatHebrewMonthName(DateTime time, int month, int repeatCount, DateTimeFormatInfo dtfi) { if (dtfi.Calendar.IsLeapYear(dtfi.Calendar.GetYear(time))) { return dtfi.internalGetMonthName(month, MonthNameStyles.LeapYear, repeatCount == 3); } if (month >= 7) { month++; } if (repeatCount == 3) { return dtfi.GetAbbreviatedMonthName(month); } return dtfi.GetMonthName(month); }
private static string FormatCustomized(DateTime dateTime, string format, DateTimeFormatInfo dtfi, TimeSpan offset) { int num2; Calendar calendar = dtfi.Calendar; StringBuilder outputBuffer = new StringBuilder(); bool flag = calendar.ID == 8; bool timeOnly = true; for (int i = 0; i < format.Length; i += num2) { int num4; int dayOfMonth; int num8; int month; int year; char patternChar = format[i]; switch (patternChar) { case 'F': case 'f': break; case 'H': { num2 = ParseRepeatPattern(format, i, patternChar); FormatDigits(outputBuffer, dateTime.Hour, num2); continue; } case ':': { outputBuffer.Append(dtfi.TimeSeparator); num2 = 1; continue; } case '/': { outputBuffer.Append(dtfi.DateSeparator); num2 = 1; continue; } case '%': { num4 = ParseNextChar(format, i); if ((num4 < 0) || (num4 == 0x25)) { throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } char ch3 = (char) num4; outputBuffer.Append(FormatCustomized(dateTime, ch3.ToString(), dtfi, offset)); num2 = 2; continue; } case '\'': case '"': { StringBuilder result = new StringBuilder(); num2 = ParseQuoteString(format, i, result); outputBuffer.Append(result); continue; } case 'K': { num2 = 1; FormatCustomizedRoundripTimeZone(dateTime, offset, outputBuffer); continue; } case 'M': num2 = ParseRepeatPattern(format, i, patternChar); month = calendar.GetMonth(dateTime); if (num2 > 2) { goto Label_03D3; } if (!flag) { goto Label_03C7; } HebrewFormatDigits(outputBuffer, month); goto Label_042E; case '\\': { num4 = ParseNextChar(format, i); if (num4 < 0) { throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } outputBuffer.Append((char) num4); num2 = 2; continue; } case 'd': num2 = ParseRepeatPattern(format, i, patternChar); if (num2 > 2) { goto Label_037F; } dayOfMonth = calendar.GetDayOfMonth(dateTime); if (!flag) { goto Label_0373; } HebrewFormatDigits(outputBuffer, dayOfMonth); goto Label_0399; case 'g': { num2 = ParseRepeatPattern(format, i, patternChar); outputBuffer.Append(dtfi.GetEraName(calendar.GetEra(dateTime))); continue; } case 'h': { num2 = ParseRepeatPattern(format, i, patternChar); int num3 = dateTime.Hour % 12; if (num3 == 0) { num3 = 12; } FormatDigits(outputBuffer, num3, num2); continue; } case 's': { num2 = ParseRepeatPattern(format, i, patternChar); FormatDigits(outputBuffer, dateTime.Second, num2); continue; } case 't': { num2 = ParseRepeatPattern(format, i, patternChar); if (num2 != 1) { goto Label_0327; } if (dateTime.Hour >= 12) { goto Label_02FE; } if (dtfi.AMDesignator.Length >= 1) { outputBuffer.Append(dtfi.AMDesignator[0]); } continue; } case 'm': { num2 = ParseRepeatPattern(format, i, patternChar); FormatDigits(outputBuffer, dateTime.Minute, num2); continue; } case 'y': year = calendar.GetYear(dateTime); num2 = ParseRepeatPattern(format, i, patternChar); if (!dtfi.HasForceTwoDigitYears) { goto Label_0466; } FormatDigits(outputBuffer, year, (num2 <= 2) ? num2 : 2); goto Label_04B5; case 'z': { num2 = ParseRepeatPattern(format, i, patternChar); FormatCustomizedTimeZone(dateTime, offset, format, num2, timeOnly, outputBuffer); continue; } default: goto Label_05A4; } num2 = ParseRepeatPattern(format, i, patternChar); if (num2 > 7) { throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } long num5 = dateTime.Ticks % 0x989680L; num5 /= (long) Math.Pow(10.0, (double) (7 - num2)); if (patternChar == 'f') { outputBuffer.Append(((int) num5).ToString(fixedNumberFormats[num2 - 1], CultureInfo.InvariantCulture)); continue; } int num6 = num2; while (num6 > 0) { if ((num5 % 10L) != 0L) { break; } num5 /= 10L; num6--; } if (num6 > 0) { outputBuffer.Append(((int) num5).ToString(fixedNumberFormats[num6 - 1], CultureInfo.InvariantCulture)); } else if ((outputBuffer.Length > 0) && (outputBuffer[outputBuffer.Length - 1] == '.')) { outputBuffer.Remove(outputBuffer.Length - 1, 1); } continue; Label_02FE: if (dtfi.PMDesignator.Length >= 1) { outputBuffer.Append(dtfi.PMDesignator[0]); } continue; Label_0327: outputBuffer.Append((dateTime.Hour < 12) ? dtfi.AMDesignator : dtfi.PMDesignator); continue; Label_0373: FormatDigits(outputBuffer, dayOfMonth, num2); goto Label_0399; Label_037F: num8 = (int) calendar.GetDayOfWeek(dateTime); outputBuffer.Append(FormatDayOfWeek(num8, num2, dtfi)); Label_0399: timeOnly = false; continue; Label_03C7: FormatDigits(outputBuffer, month, num2); goto Label_042E; Label_03D3: if (flag) { outputBuffer.Append(FormatHebrewMonthName(dateTime, month, num2, dtfi)); } else if (((dtfi.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != DateTimeFormatFlags.None) && (num2 >= 4)) { outputBuffer.Append(dtfi.internalGetMonthName(month, IsUseGenitiveForm(format, i, num2, 'd') ? MonthNameStyles.Genitive : MonthNameStyles.Regular, false)); } else { outputBuffer.Append(FormatMonth(month, num2, dtfi)); } Label_042E: timeOnly = false; continue; Label_0466: if (calendar.ID == 8) { HebrewFormatDigits(outputBuffer, year); } else if (num2 <= 2) { FormatDigits(outputBuffer, year % 100, num2); } else { string str = "D" + num2; outputBuffer.Append(year.ToString(str, CultureInfo.InvariantCulture)); } Label_04B5: timeOnly = false; continue; Label_05A4: outputBuffer.Append(patternChar); num2 = 1; } return outputBuffer.ToString(); }
private static string FormatCustomized(DateTime dateTime, string format, DateTimeFormatInfo dtfi, TimeSpan offset) { Calendar calendar = dtfi.Calendar; StringBuilder stringBuilder = new StringBuilder(); bool flag = calendar.ID == 8; bool timeOnly = true; int i = 0; while (i < format.Length) { char c = format[i]; char c2 = c; int num2; if (c2 <= 'H') { if (c2 <= '\'') { if (c2 != '"') { switch (c2) { case '%': { int num = DateTimeFormat.ParseNextChar(format, i); if (num >= 0 && num != 37) { stringBuilder.Append(DateTimeFormat.FormatCustomized(dateTime, ((char)num).ToString(), dtfi, offset)); num2 = 2; goto IL_5B0; } throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } case '&': { goto IL_5A4; } case '\'': { break; } default: { goto IL_5A4; } } } StringBuilder stringBuilder2 = new StringBuilder(); num2 = DateTimeFormat.ParseQuoteString(format, i, stringBuilder2); stringBuilder.Append(stringBuilder2); } else { if (c2 != '/') { if (c2 != ':') { switch (c2) { case 'F': { goto IL_1BA; } case 'G': { goto IL_5A4; } case 'H': { num2 = DateTimeFormat.ParseRepeatPattern(format, i, c); DateTimeFormat.FormatDigits(stringBuilder, dateTime.Hour, num2); break; } default: { goto IL_5A4; } } } else { stringBuilder.Append(dtfi.TimeSeparator); num2 = 1; } } else { stringBuilder.Append(dtfi.DateSeparator); num2 = 1; } } } else { if (c2 <= 'h') { switch (c2) { case 'K': { num2 = 1; DateTimeFormat.FormatCustomizedRoundripTimeZone(dateTime, offset, stringBuilder); break; } case 'L': { goto IL_5A4; } case 'M': { num2 = DateTimeFormat.ParseRepeatPattern(format, i, c); int month = calendar.GetMonth(dateTime); if (num2 <= 2) { if (flag) { DateTimeFormat.HebrewFormatDigits(stringBuilder, month); } else { DateTimeFormat.FormatDigits(stringBuilder, month, num2); } } else { if (flag) { stringBuilder.Append(DateTimeFormat.FormatHebrewMonthName(dateTime, month, num2, dtfi)); } else { if ((dtfi.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != DateTimeFormatFlags.None && num2 >= 4) { stringBuilder.Append(dtfi.internalGetMonthName(month, DateTimeFormat.IsUseGenitiveForm(format, i, num2, 'd') ? MonthNameStyles.Genitive : MonthNameStyles.Regular, false)); } else { stringBuilder.Append(DateTimeFormat.FormatMonth(month, num2, dtfi)); } } } timeOnly = false; break; } default: { if (c2 != '\\') { switch (c2) { case 'd': { num2 = DateTimeFormat.ParseRepeatPattern(format, i, c); if (num2 <= 2) { int dayOfMonth = calendar.GetDayOfMonth(dateTime); if (flag) { DateTimeFormat.HebrewFormatDigits(stringBuilder, dayOfMonth); } else { DateTimeFormat.FormatDigits(stringBuilder, dayOfMonth, num2); } } else { int dayOfWeek = (int)calendar.GetDayOfWeek(dateTime); stringBuilder.Append(DateTimeFormat.FormatDayOfWeek(dayOfWeek, num2, dtfi)); } timeOnly = false; break; } case 'e': { goto IL_5A4; } case 'f': { goto IL_1BA; } case 'g': { num2 = DateTimeFormat.ParseRepeatPattern(format, i, c); stringBuilder.Append(dtfi.GetEraName(calendar.GetEra(dateTime))); break; } case 'h': { num2 = DateTimeFormat.ParseRepeatPattern(format, i, c); int num3 = dateTime.Hour % 12; if (num3 == 0) { num3 = 12; } DateTimeFormat.FormatDigits(stringBuilder, num3, num2); break; } default: { goto IL_5A4; } } } else { int num = DateTimeFormat.ParseNextChar(format, i); if (num < 0) { throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } stringBuilder.Append((char)num); num2 = 2; } break; } } } else { if (c2 != 'm') { switch (c2) { case 's': { num2 = DateTimeFormat.ParseRepeatPattern(format, i, c); DateTimeFormat.FormatDigits(stringBuilder, dateTime.Second, num2); break; } case 't': { num2 = DateTimeFormat.ParseRepeatPattern(format, i, c); if (num2 == 1) { if (dateTime.Hour < 12) { if (dtfi.AMDesignator.Length >= 1) { stringBuilder.Append(dtfi.AMDesignator[0]); } } else { if (dtfi.PMDesignator.Length >= 1) { stringBuilder.Append(dtfi.PMDesignator[0]); } } } else { stringBuilder.Append((dateTime.Hour < 12) ? dtfi.AMDesignator : dtfi.PMDesignator); } break; } default: { switch (c2) { case 'y': { int year = calendar.GetYear(dateTime); num2 = DateTimeFormat.ParseRepeatPattern(format, i, c); if (dtfi.HasForceTwoDigitYears) { DateTimeFormat.FormatDigits(stringBuilder, year, (num2 <= 2) ? num2 : 2); } else { if (calendar.ID == 8) { DateTimeFormat.HebrewFormatDigits(stringBuilder, year); } else { if (num2 <= 2) { DateTimeFormat.FormatDigits(stringBuilder, year % 100, num2); } else { string format2 = "D" + num2; stringBuilder.Append(year.ToString(format2, CultureInfo.InvariantCulture)); } } } timeOnly = false; break; } case 'z': { num2 = DateTimeFormat.ParseRepeatPattern(format, i, c); DateTimeFormat.FormatCustomizedTimeZone(dateTime, offset, format, num2, timeOnly, stringBuilder); break; } default: { goto IL_5A4; } } break; } } } else { num2 = DateTimeFormat.ParseRepeatPattern(format, i, c); DateTimeFormat.FormatDigits(stringBuilder, dateTime.Minute, num2); } } } IL_5B0: i += num2; continue; IL_1BA: num2 = DateTimeFormat.ParseRepeatPattern(format, i, c); if (num2 > 7) { throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } long num4 = dateTime.Ticks % 10000000L; num4 /= (long)Math.Pow(10.0, (double)(7 - num2)); if (c == 'f') { stringBuilder.Append(((int)num4).ToString(DateTimeFormat.fixedNumberFormats[num2 - 1], CultureInfo.InvariantCulture)); goto IL_5B0; } int num5 = num2; while (num5 > 0 && num4 % 10L == 0L) { num4 /= 10L; num5--; } if (num5 > 0) { stringBuilder.Append(((int)num4).ToString(DateTimeFormat.fixedNumberFormats[num5 - 1], CultureInfo.InvariantCulture)); goto IL_5B0; } if (stringBuilder.Length > 0 && stringBuilder[stringBuilder.Length - 1] == '.') { stringBuilder.Remove(stringBuilder.Length - 1, 1); goto IL_5B0; } goto IL_5B0; IL_5A4: stringBuilder.Append(c); num2 = 1; goto IL_5B0; } return stringBuilder.ToString(); }
// // FormatCustomized // // Actions: Format the DateTime instance using the specified format. // private static String FormatCustomized(DateTime dateTime, String format, DateTimeFormatInfo dtfi) { Calendar cal = dtfi.Calendar; StringBuilder result = new StringBuilder(); // This is a flag to indicate if we are format the dates using Hebrew calendar. bool isHebrewCalendar = (cal.ID == Calendar.CAL_HEBREW); // This is a flag to indicate if we are formating hour/minute/second only. bool bTimeOnly = true; int i = 0; int tokenLen, hour12; while (i < format.Length) { char ch = format[i]; int nextChar; switch (ch) { case 'g': tokenLen = ParseRepeatPattern(format, i, ch); result.Append(dtfi.GetEraName(cal.GetEra(dateTime))); break; case 'h': tokenLen = ParseRepeatPattern(format, i, ch); hour12 = dateTime.Hour % 12; if (hour12 == 0) { hour12 = 12; } FormatDigits(result, hour12, tokenLen); break; case 'H': tokenLen = ParseRepeatPattern(format, i, ch); FormatDigits(result, dateTime.Hour, tokenLen); break; case 'm': tokenLen = ParseRepeatPattern(format, i, ch); FormatDigits(result, dateTime.Minute, tokenLen); break; case 's': tokenLen = ParseRepeatPattern(format, i, ch); FormatDigits(result, dateTime.Second, tokenLen); break; case 'f': case 'F': tokenLen = ParseRepeatPattern(format, i, ch); if (tokenLen <= MaxSecondsFractionDigits) { long fraction = (dateTime.Ticks % Calendar.TicksPerSecond); fraction = fraction / (long)Math.Pow(10, 7 - tokenLen); if (ch == 'f') { result.Append(((int)fraction).ToString(fixedNumberFormats[tokenLen - 1], CultureInfo.InvariantCulture)); } else { int effectiveDigits = tokenLen; while (effectiveDigits > 0) { if (fraction % 10 == 0) { fraction = fraction / 10; effectiveDigits--; } else { break; } } if (effectiveDigits > 0) { result.Append(((int)fraction).ToString(fixedNumberFormats[effectiveDigits - 1], CultureInfo.InvariantCulture)); } else { // No fraction to emit, so see if we should remove decimal also. if (result.Length > 0 && result[result.Length - 1] == '.') { result.Remove(result.Length - 1, 1); } } } } else { throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } break; case 't': tokenLen = ParseRepeatPattern(format, i, ch); if (tokenLen == 1) { if (dateTime.Hour < 12) { if (dtfi.AMDesignator.Length >= 1) { result.Append(dtfi.AMDesignator[0]); } } else { if (dtfi.PMDesignator.Length >= 1) { result.Append(dtfi.PMDesignator[0]); } } } else { result.Append((dateTime.Hour < 12 ? dtfi.AMDesignator : dtfi.PMDesignator)); } break; case 'd': // // tokenLen == 1 : Day of month as digits with no leading zero. // tokenLen == 2 : Day of month as digits with leading zero for single-digit months. // tokenLen == 3 : Day of week as a three-leter abbreviation. // tokenLen >= 4 : Day of week as its full name. // tokenLen = ParseRepeatPattern(format, i, ch); if (tokenLen <= 2) { int day = cal.GetDayOfMonth(dateTime); if (isHebrewCalendar) { // For Hebrew calendar, we need to convert numbers to Hebrew text for yyyy, MM, and dd values. HebrewFormatDigits(result, day); } else { FormatDigits(result, day, tokenLen); } } else { int dayOfWeek = (int)cal.GetDayOfWeek(dateTime); result.Append(FormatDayOfWeek(dayOfWeek, tokenLen, dtfi)); } bTimeOnly = false; break; case 'M': // // tokenLen == 1 : Month as digits with no leading zero. // tokenLen == 2 : Month as digits with leading zero for single-digit months. // tokenLen == 3 : Month as a three-letter abbreviation. // tokenLen >= 4 : Month as its full name. // tokenLen = ParseRepeatPattern(format, i, ch); int month = cal.GetMonth(dateTime); if (tokenLen <= 2) { if (isHebrewCalendar) { // For Hebrew calendar, we need to convert numbers to Hebrew text for yyyy, MM, and dd values. HebrewFormatDigits(result, month); } else { FormatDigits(result, month, tokenLen); } } else { if (isHebrewCalendar) { result.Append(FormatHebrewMonthName(dateTime, month, tokenLen, dtfi)); } else { if ((dtfi.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0 && tokenLen >= 4) { result.Append( dtfi.internalGetMonthName( month, IsUseGenitiveForm(format, i, tokenLen, 'd')? MonthNameStyles.Genitive : MonthNameStyles.Regular, false)); } else { result.Append(FormatMonth(month, tokenLen, dtfi)); } } } bTimeOnly = false; break; case 'y': // Notes about OS behavior: // y: Always print (year % 100). No leading zero. // yy: Always print (year % 100) with leading zero. // yyy/yyyy/yyyyy/... : Print year value. No leading zero. int year = cal.GetYear(dateTime); tokenLen = ParseRepeatPattern(format, i, ch); if (dtfi.HasForceTwoDigitYears) { FormatDigits(result, year, tokenLen <= 2 ? tokenLen : 2); } else if (cal.ID == Calendar.CAL_HEBREW) { HebrewFormatDigits(result, year); } else { if (tokenLen <= 2) { FormatDigits(result, year % 100, tokenLen); } else { String fmtPattern = "D" + tokenLen; result.Append(year.ToString(fmtPattern, CultureInfo.InvariantCulture)); } } bTimeOnly = false; break; case 'z': // // Output the offset of the timezone according to the system timezone setting. // tokenLen = ParseRepeatPattern(format, i, ch); TimeSpan offset; if (bTimeOnly && dateTime.Ticks < Calendar.TicksPerDay) { offset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now); } else { if (dateTime.Kind == DateTimeKind.Utc) { InvalidFormatForUtc(format, dateTime); offset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.SpecifyKind(dateTime, DateTimeKind.Local)); } else { offset = TimeZone.CurrentTimeZone.GetUtcOffset(dateTime); } } switch (tokenLen) { case 1: result.Append((offset.Hours).ToString("+0;-0", CultureInfo.InvariantCulture)); break; case 2: result.Append((offset.Hours).ToString("+00;-00", CultureInfo.InvariantCulture)); break; default: if (offset.Ticks >= 0) { result.Append(String.Format(CultureInfo.InvariantCulture, "+{0:00}:{1:00}", offset.Hours, offset.Minutes)); } else { // When the offset is negative, note that the offset.Minute is also negative. // So use should use -offset.Minute to get the postive value. result.Append(String.Format(CultureInfo.InvariantCulture, "-{0:00}:{1:00}", -offset.Hours, -offset.Minutes)); } break; } break; case 'K': tokenLen = 1; // The objective of this format is to round trip the Kind value and preserve the time zone switch (dateTime.Kind) { case DateTimeKind.Local: // This should output the local offset, e.g. "-07:00" TimeSpan localOffset = TimeZone.CurrentTimeZone.GetUtcOffset(dateTime); if (localOffset.Ticks >= 0) { result.Append(String.Format(CultureInfo.InvariantCulture, "+{0:00}:{1:00}", localOffset.Hours, localOffset.Minutes)); } else { // When the offset is negative, note that the localOffset.Minute is also negative. // So use should use -localOffset.Minute to get the postive value. result.Append(String.Format(CultureInfo.InvariantCulture, "-{0:00}:{1:00}", -localOffset.Hours, -localOffset.Minutes)); } break; case DateTimeKind.Utc: // The 'Z' constant is a marker for a UTC date result.Append("Z"); break; default: // If the kind is unspecified, we output nothing here break; } break; case ':': result.Append(dtfi.TimeSeparator); tokenLen = 1; break; case '/': result.Append(dtfi.DateSeparator); tokenLen = 1; break; case '\'': case '\"': StringBuilder enquotedString = new StringBuilder(); tokenLen = ParseQuoteString(format, i, enquotedString); result.Append(enquotedString); break; case '%': // Optional format character. // For example, format string "%d" will print day of month // without leading zero. Most of the cases, "%" can be ignored. nextChar = ParseNextChar(format, i); // nextChar will be -1 if we already reach the end of the format string. // Besides, we will not allow "%%" appear in the pattern. if (nextChar >= 0 && nextChar != (int)'%') { result.Append(FormatCustomized(dateTime, ((char)nextChar).ToString(), dtfi)); tokenLen = 2; } else { // // This means that '%' is at the end of the format string or // "%%" appears in the format string. // throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } break; case '\\': // nextChar = ParseNextChar(format, i); if (nextChar >= 0) { result.Append(((char)nextChar)); tokenLen = 2; } else { // // This means that '\' is at the end of the formatting string. // throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } break; default: result.Append(ch); tokenLen = 1; break; } i += tokenLen; } return (result.ToString()); }