Exemple #1
0
        //
        //  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);

        }
		private static bool MatchEraName(ref __DTString str, DateTimeFormatInfo dtfi, ref int result)
		{
			if (str.GetNext())
			{
				int[] eras = dtfi.Calendar.Eras;
				if (eras != null)
				{
					for (int i = 0; i < eras.Length; i++)
					{
						string text = dtfi.GetEraName(eras[i]);
						if (str.MatchSpecifiedWord(text))
						{
							str.Index += text.Length - 1;
							result = eras[i];
							return true;
						}
						text = dtfi.GetAbbreviatedEraName(eras[i]);
						if (str.MatchSpecifiedWord(text))
						{
							str.Index += text.Length - 1;
							result = eras[i];
							return true;
						}
					}
				}
			}
			return false;
		}
Exemple #3
0
        /// <summary>
        /// Returns a string representation of this object.
        /// </summary>
        /// <param name="format">
        /// The format pattern.
        /// </param>
        /// <param name="dtfi">
        /// The <see cref="DateTimeFormatInfo"/> to use for formatting.
        /// </param>
        /// <param name="nameProvider">
        /// The day and month name provider.
        /// </param>
        /// <param name="nativeDigits">
        /// If not <c>null</c> and valid, uses for number representation the specified native digits.
        /// </param>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        private string ToString(string format, DateTimeFormatInfo dtfi, ICustomFormatProvider nameProvider, string[] nativeDigits = null)
        {
            if (dtfi == null)
            {
                dtfi = CultureInfo.CurrentUICulture.DateTimeFormat;
            }

            if (string.IsNullOrEmpty(format))
            {
                format = nameProvider != null ? nameProvider.ShortDatePattern : dtfi.ShortDatePattern;
            }
            else if (format.Length == 1)
            {
                switch (format[0])
                {
                    case 'D':
                        {
                            format = nameProvider != null ? nameProvider.LongDatePattern : dtfi.LongDatePattern;

                            break;
                        }

                    case 'm':
                    case 'M':
                        {
                            format = nameProvider != null ? nameProvider.MonthDayPattern : dtfi.MonthDayPattern;

                            break;
                        }

                    case 'y':
                    case 'Y':
                        {
                            format = nameProvider != null ? nameProvider.YearMonthPattern : dtfi.YearMonthPattern;

                            break;
                        }

                    default:
                        {
                            format = nameProvider != null ? nameProvider.ShortDatePattern : dtfi.ShortDatePattern;

                            break;
                        }
                }
            }

            format = format.Replace(nameProvider != null ? nameProvider.DateSeparator : dtfi.DateSeparator, "/");

            StringBuilder sb = new StringBuilder();

            Calendar c = nameProvider != null ? nameProvider.Calendar : dtfi.Calendar;

            int i = 0;

            while (i < format.Length)
            {
                int tokLen;
                char ch = format[i];

                switch (ch)
                {
                    case 'd':
                        {
                            tokLen = CountChar(format, i, ch);

                            sb.Append(
                                tokLen <= 2
                                    ? DateMethods.GetNumberString(this.Day, nativeDigits, tokLen == 2)
                                    : GetDayName(c.GetDayOfWeek(this.Date), dtfi, nameProvider, tokLen == 3));

                            break;
                        }

                    case 'M':
                        {
                            tokLen = CountChar(format, i, ch);

                            sb.Append(
                                tokLen <= 2
                                    ? DateMethods.GetNumberString(this.Month, nativeDigits, tokLen == 2)
                                    : GetMonthName(this.Month, this.Year, dtfi, nameProvider, tokLen == 3));

                            break;
                        }

                    case 'y':
                        {
                            tokLen = CountChar(format, i, ch);

                            sb.Append(
                                tokLen <= 2
                                    ? DateMethods.GetNumberString(this.Year % 100, nativeDigits, true)
                                    : DateMethods.GetNumberString(this.Year, nativeDigits, false));

                            break;
                        }

                    case 'g':
                        {
                            tokLen = CountChar(format, i, ch);

                            sb.Append(nameProvider != null ? nameProvider.GetEraName(c.GetEra(this.Date)) : dtfi.GetEraName(c.GetEra(this.Date)));

                            break;
                        }

                    case '/':
                        {
                            tokLen = CountChar(format, i, ch);

                            sb.Append(nameProvider != null ? nameProvider.DateSeparator : dtfi.DateSeparator);

                            break;
                        }

                    case '\'':
                        {
                            tokLen = 1;

                            break;
                        }

                    default:
                        {
                            tokLen = 1;

                            sb.Append(ch.ToString(CultureInfo.CurrentUICulture));

                            break;
                        }
                }

                i += tokLen;
            }

            return sb.ToString();
        }
 private static JObject CreateDateInfoJson(DateTimeFormatInfo di)
 {
     var obj = new
     {
         firstDay = di.FirstDayOfWeek,
         days = new
         {
             names = di.DayNames,
             namesAbbr = di.AbbreviatedDayNames,
             namesShort = di.ShortestDayNames
         },
         months = new
         {
             names = di.MonthNames,
             namesAbbr = di.AbbreviatedMonthNames
         },
         AM = di.AMDesignator,
         PM = di.PMDesignator,
         eras = di.Calendar.Eras.Select(era => new { offset = 0, start = (string)null, name = di.GetEraName(era) }).ToArray(),
         twoDigitYearMax = di.Calendar.TwoDigitYearMax,
         patterns = new
         {
             d = di.ShortDatePattern,
             D = di.LongDatePattern,
             t = di.ShortTimePattern,
             T = di.LongTimePattern,
             f = di.LongDatePattern + " " + di.ShortTimePattern,
             F = di.LongDatePattern + " " + di.LongTimePattern,
             M = di.MonthDayPattern,
             Y = di.YearMonthPattern,
         }
     };
     var jobj = JObject.FromObject(obj);
     jobj["/"] = di.DateSeparator;
     jobj[":"] = di.TimeSeparator;
     if (!di.MonthNames.SequenceEqual(di.MonthGenitiveNames))
     {
         var monthsGenitive = jobj["monthsGenitive"] = new JObject();
         monthsGenitive["names"] = JArray.FromObject(di.MonthGenitiveNames);
         monthsGenitive["namesAbbr"] = JArray.FromObject(di.AbbreviatedMonthGenitiveNames);
     }
     return new JObject()
     {
         {"standard", jobj }
     };
 }
	// Format a date value as a string using a particular pattern format.
	public static String Format(String format, DateTime date,
								DateTimeFormatInfo info)
			{
				// Format the date/time value.
				StringBuilder builder = new StringBuilder();
				int posn = 0;
				char ch;
				int count, value;
				while(posn < format.Length)
				{
					// Extract the next format character plus its count.
					ch = format[posn++];
					count = 1;
					switch(ch)
					{
						case 'd': case 'm': case 'M': case 'y':
						case 'g': case 'h': case 'H': case 's':
						case 'f': case 't': case 'z':
						{
							while(posn < format.Length &&
								  format[posn] == ch)
							{
								++posn;
								++count;
							}
						}
						break;

						case ':':
						{
							builder.Append(info.TimeSeparator);
							continue;
						}
						// Not reached.

						case '/':
						{
							builder.Append(info.DateSeparator);
							continue;
						}
						// Not reached.

						case '%':
						{
							// Used to escape custom patterns that would
							// otherwise look like single-letter formats.
							continue;
						}
						// Not reached.

						case '\\':
						{
							// Escape the next character.
							if(posn < format.Length)
							{
								builder.Append(format[posn++]);
							}
							continue;
						}
						// Not reached.

						case '\'':
						{
							// Quoted text.
							while(posn < format.Length)
							{
								ch = format[posn++];
								if(ch == '\'')
								{
									break;
								}
								builder.Append(ch);
							}
							continue;
						}
						// Not reached.

						default:
						{
							// Literal character.
							builder.Append(ch);
							continue;
						}
						// Not reached.
					}

					// Process the format character.
					switch(ch)
					{
						case 'd':
						{
							// Output the day or weekday.
							if(count == 1)
							{
								value = date.Day;
								if(value < 10)
								{
									builder.Append((char)('0' + value));
								}
								else
								{
									builder.Append((char)('0' + (value / 10)));
									builder.Append((char)('0' + (value % 10)));
								}
							}
							else if(count == 2)
							{
								value = date.Day;
								builder.Append((char)('0' + (value / 10)));
								builder.Append((char)('0' + (value % 10)));
							}
							else if(count == 3)
							{
								builder.Append
									(info.AbbreviatedDayNames
										[(int)(date.DayOfWeek)]);
							}
							else
							{
								builder.Append
									(info.DayNames[(int)(date.DayOfWeek)]);
							}
						}
						break;

						case 'M':
						{
							// Output the month.
							value = date.Month;
							if(count == 1)
							{
								if(value < 10)
								{
									builder.Append((char)('0' + value));
								}
								else
								{
									builder.Append((char)('0' + (value / 10)));
									builder.Append((char)('0' + (value % 10)));
								}
							}
							else if(count == 2)
							{
								builder.Append((char)('0' + (value / 10)));
								builder.Append((char)('0' + (value % 10)));
							}
							else if(count == 3)
							{
								builder.Append
									(info.AbbreviatedMonthNames[value - 1]);
							}
							else
							{
								builder.Append(info.MonthNames[value - 1]);
							}
						}
						break;

						case 'y':
						{
							// Output the year.
							value = date.Year;
							if(count == 1)
							{
								value %= 100;
								if(value < 10)
								{
									builder.Append((char)('0' + value));
								}
								else
								{
									builder.Append((char)('0' + (value / 10)));
									builder.Append((char)('0' + (value % 10)));
								}
							}
							else if(count == 2)
							{
								value %= 100;
								builder.Append((char)('0' + (value / 10)));
								builder.Append((char)('0' + (value % 10)));
							}
							else
							{
								builder.Append((char)('0' + (value / 1000)));
								builder.Append
									((char)('0' + ((value / 100 % 10))));
								builder.Append
									((char)('0' + ((value / 10 % 10))));
								builder.Append((char)('0' + (value % 10)));
							}
						}
						break;

						case 'g':
						{
							// Output the era name.
							try
							{
								int era = info.Calendar.GetEra(date);
								builder.Append(info.GetEraName(era));
							}
							catch(ArgumentException)
							{
								// The date does not have an era.
							}
						}
						break;

						case 'h':
						{
							// Output the hour in 12-hour format.
							value = date.Hour;
							if(value == 0)
							{
								value = 12;
							}
							else if(value > 12)
							{
								value -= 12;
							}
							if(count == 1)
							{
								if(value < 10)
								{
									builder.Append((char)('0' + value));
								}
								else
								{
									builder.Append((char)('0' + (value / 10)));
									builder.Append((char)('0' + (value % 10)));
								}
							}
							else
							{
								builder.Append((char)('0' + (value / 10)));
								builder.Append((char)('0' + (value % 10)));
							}
						}
						break;

						case 'H':
						{
							// Output the hour in 24-hour format.
							value = date.Hour;
							if(count == 1)
							{
								if(value < 10)
								{
									builder.Append((char)('0' + value));
								}
								else
								{
									builder.Append((char)('0' + (value / 10)));
									builder.Append((char)('0' + (value % 10)));
								}
							}
							else
							{
								builder.Append((char)('0' + (value / 10)));
								builder.Append((char)('0' + (value % 10)));
							}
						}
						break;

						case 'm':
						{
							// Output the minute.
							value = date.Minute;
							if(count == 1)
							{
								if(value < 10)
								{
									builder.Append((char)('0' + value));
								}
								else
								{
									builder.Append((char)('0' + (value / 10)));
									builder.Append((char)('0' + (value % 10)));
								}
							}
							else
							{
								builder.Append((char)('0' + (value / 10)));
								builder.Append((char)('0' + (value % 10)));
							}
						}
						break;

						case 's':
						{
							// Output the second.
							value = date.Second;
							if(count == 1)
							{
								if(value < 10)
								{
									builder.Append((char)('0' + value));
								}
								else
								{
									builder.Append((char)('0' + (value / 10)));
									builder.Append((char)('0' + (value % 10)));
								}
							}
							else
							{
								builder.Append((char)('0' + (value / 10)));
								builder.Append((char)('0' + (value % 10)));
							}
						}
						break;

						case 'f':
						{
							// Output fractions of a second.
							if(count > 7)
							{
								count = 7;
							}
							long frac = date.Ticks;
							long divisor = TimeSpan.TicksPerSecond;
							while(count > 0)
							{
								divisor /= 10;
								value = (int)((frac / divisor) % 10);
								builder.Append((char)('0' + value));
								frac %= divisor;
								--count;
							}
						}
						break;

						case 't':
						{
							value = date.Hour;
							if(count == 1)
							{
								if(value < 12)
								{
									builder.Append(info.AMDesignator[0]);
								}
								else
								{
									builder.Append(info.PMDesignator[0]);
								}
							}
							else
							{
								if(value < 12)
								{
									builder.Append(info.AMDesignator);
								}
								else
								{
									builder.Append(info.PMDesignator);
								}
							}
						}
						break;

					#if !ECMA_COMPAT
						case 'z':
						{
							long offset =
								TimeZone.CurrentTimeZone
									.GetUtcOffset(date).Ticks;
							int hour, min;
							if(offset >= 0)
							{
								builder.Append('+');
							}
							else
							{
								builder.Append('-');
								offset = -offset;
							}
							hour = (int)(offset / TimeSpan.TicksPerHour);
							offset %= TimeSpan.TicksPerHour;
							min = (int)(offset / TimeSpan.TicksPerMinute);
							if(count == 1)
							{
								if(hour < 10)
								{
									builder.Append((char)('0' + hour));
								}
								else
								{
									builder.Append((char)('0' + (hour / 10)));
									builder.Append((char)('0' + (hour % 10)));
								}
							}
							else if(count == 2)
							{
								builder.Append((char)('0' + (hour / 10)));
								builder.Append((char)('0' + (hour % 10)));
							}
							else
							{
								builder.Append((char)('0' + (hour / 10)));
								builder.Append((char)('0' + (hour % 10)));
								builder.Append(':');
								builder.Append((char)('0' + (min / 10)));
								builder.Append((char)('0' + (min % 10)));
							}
						}
						break;
					#endif
					}
				}

				// Return the formatted string to the caller.
				return builder.ToString();
			}
 private ClientCultureInfo(CultureInfo cultureInfo) {
     name = cultureInfo.Name;
     numberFormat = cultureInfo.NumberFormat;
     dateTimeFormat = cultureInfo.DateTimeFormat;
     var calendar = dateTimeFormat == null ? null : dateTimeFormat.Calendar;
     if (calendar != null) {
         // Dev10 425049: Support Eras for gregorian based calendars
         // with a simple year offset, and non-gregorian calendars.
         // Era data is stored in binary resource "culture.nlp" in mscorlib,
         // hard coded here for simplicity.
         // era array has the following structure:
         // [eraNumber1, eraName1, eraStartInTicks1, eraGregorianYearOffset1, eraNumber2, ...]
         eras = new object[calendar.Eras.Length * 4];
         int i = 0;
         foreach (int era in calendar.Eras) {
             // era number
             eras[i + eraNumber] = era;
             // era name
             eras[i + eraName] = dateTimeFormat.GetEraName(era);
             // calendars with only one era will have a null tick count
             // signifying that the era starts from the lowest datetime
             // era begining in ticks (null = the oldest era)
             // eras[i + eraStart] = null;
             // era year offset from normal gregorian year
             // some calendars dont have an offset, just a different name
             // for the A.D. era (B.C. is not supported by normal calendar,
             // so most calendars only have 1 era)
             eras[i + eraYearOffset] = 0;
             i += 4;
         }
         var calendarType = calendar.GetType();
         if (calendarType != typeof(GregorianCalendar)) {
             if (calendarType == typeof(TaiwanCalendar)) {
                 // Only the current era is supported, so no tick count is needed
                 //eras[eraStart] = -1830384000000;
                 eras[eraYearOffset] = 1911;
             }
             else if (calendarType == typeof(KoreanCalendar)) {
                 // only one era to speak of, so no tick count is needed
                 //eras[eraStart] = -62135596800000;
                 eras[eraYearOffset] = -2333;
             }
             else if (calendarType == typeof(ThaiBuddhistCalendar)) {
                 // only one era to speak of, so no tick count is needed
                 //eras[eraStart] = -62135596800000;
                 eras[eraYearOffset] = -543;
             }
             else if (calendarType == typeof(JapaneseCalendar)) {
                 // there are multiple eras
                 eras[0 + eraStart] = 60022080000;
                 eras[0 + eraYearOffset] = 1988;
                 eras[4 + eraStart] = -1357603200000;
                 eras[4 + eraYearOffset] = 1925;
                 eras[8 + eraStart] = -1812153600000;
                 eras[8 + eraYearOffset] = 1911;
                 // oldest era is technically from this offset, but for simplicity
                 // it is counted from the lowest date time, so no tick count needed.
                 //eras[12 + eraStart] = -3218832000000;
                 eras[12 + eraYearOffset] = 1867;
             }
             else if (calendarType == typeof(HijriCalendar)) {
                 _convertScript = "Date.HijriCalendar.js";
                 _adjustment = ((HijriCalendar)calendar).HijriAdjustment;
             }
             else if (calendarType == typeof(UmAlQuraCalendar)) {
                 _convertScript = "Date.UmAlQuraCalendar.js";
             }
             // else { other calendars arent supported or have no era offsets just different names for A.D.
         }
     }
     
 }
 private void VerificationHelper(DateTimeFormatInfo info, int era, string expected)
 {
     string actual = info.GetEraName(era);
     Assert.Equal(expected, actual);
 }
		public static string ToString (DateTime dt, TimeSpan? utc_offset, string format, DateTimeFormatInfo dfi)
		{
			// the length of the format is usually a good guess of the number
			// of chars in the result. Might save us a few bytes sometimes
			// Add + 10 for cases like mmmm dddd
			StringBuilder result = new StringBuilder (format.Length + 10);

			// For some cases, the output should not use culture dependent calendar
			DateTimeFormatInfo inv = DateTimeFormatInfo.InvariantInfo;
			if (format == inv.RFC1123Pattern)
				dfi = inv;
			else if (format == inv.UniversalSortableDateTimePattern)
				dfi = inv;

			int i = 0;

			while (i < format.Length) {
				int tokLen;
				bool omitZeros = false;
				char ch = format [i];

				switch (ch) {

				//
				// Time Formats
				//
				case 'h':
					// hour, [1, 12]
					tokLen = DateTimeUtils.CountRepeat (format, i, ch);

					int hr = dt.Hour % 12;
					if (hr == 0)
						hr = 12;

					DateTimeUtils.ZeroPad (result, hr, tokLen == 1 ? 1 : 2);
					break;
				case 'H':
					// hour, [0, 23]
					tokLen = DateTimeUtils.CountRepeat (format, i, ch);
					DateTimeUtils.ZeroPad (result, dt.Hour, tokLen == 1 ? 1 : 2);
					break;
				case 'm':
					// minute, [0, 59]
					tokLen = DateTimeUtils.CountRepeat (format, i, ch);
					DateTimeUtils.ZeroPad (result, dt.Minute, tokLen == 1 ? 1 : 2);
					break;
				case 's':
					// second [0, 29]
					tokLen = DateTimeUtils.CountRepeat (format, i, ch);
					DateTimeUtils.ZeroPad (result, dt.Second, tokLen == 1 ? 1 : 2);
					break;
				case 'F':
					omitZeros = true;
					goto case 'f';
				case 'f':
					// fraction of second, to same number of
					// digits as there are f's

					tokLen = DateTimeUtils.CountRepeat (format, i, ch);
					if (tokLen > 7)
						throw new FormatException ("Invalid Format String");

					int dec = (int)((long)(dt.Ticks % TimeSpan.TicksPerSecond) / (long) Math.Pow (10, 7 - tokLen));
					int startLen = result.Length;
					DateTimeUtils.ZeroPad (result, dec, tokLen);

					if (omitZeros) {
						while (result.Length > startLen && result [result.Length - 1] == '0')
							result.Length--;
						// when the value was 0, then trim even preceding '.' (!) It is fixed character.
						if (dec == 0 && startLen > 0 && result [startLen - 1] == '.')
							result.Length--;
					}

					break;
				case 't':
					// AM/PM. t == first char, tt+ == full
					tokLen = DateTimeUtils.CountRepeat (format, i, ch);
					string desig = dt.Hour < 12 ? dfi.AMDesignator : dfi.PMDesignator;

					if (tokLen == 1) {
						if (desig.Length >= 1)
							result.Append (desig [0]);
					}
					else
						result.Append (desig);

					break;
				case 'z':
					// timezone. t = +/-h; tt = +/-hh; ttt+=+/-hh:mm
					tokLen = DateTimeUtils.CountRepeat (format, i, ch);
					TimeSpan offset = 
						utc_offset ?? 
						TimeZone.CurrentTimeZone.GetUtcOffset (dt);

					if (offset.Ticks >= 0)
						result.Append ('+');
					else
						result.Append ('-');

					switch (tokLen) {
					case 1:
						result.Append (Math.Abs (offset.Hours));
						break;
					case 2:
						result.Append (Math.Abs (offset.Hours).ToString ("00"));
						break;
					default:
						result.Append (Math.Abs (offset.Hours).ToString ("00"));
						result.Append (':');
						result.Append (Math.Abs (offset.Minutes).ToString ("00"));
						break;
					}
					break;
				case 'K': // 'Z' (UTC) or zzz (Local)
					tokLen = 1;

					if (utc_offset != null || dt.Kind == DateTimeKind.Local) {
						offset = utc_offset ?? TimeZone.CurrentTimeZone.GetUtcOffset (dt);
						if (offset.Ticks >= 0)
							result.Append ('+');
						else
							result.Append ('-');
						result.Append (Math.Abs (offset.Hours).ToString ("00"));
						result.Append (':');
						result.Append (Math.Abs (offset.Minutes).ToString ("00"));
					} else if (dt.Kind == DateTimeKind.Utc)
						result.Append ('Z');
					break;
				//
				// Date tokens
				//
				case 'd':
					// day. d(d?) = day of month (leading 0 if two d's)
					// ddd = three leter day of week
					// dddd+ full day-of-week
					tokLen = DateTimeUtils.CountRepeat (format, i, ch);

					if (tokLen <= 2)
						DateTimeUtils.ZeroPad (result, dfi.Calendar.GetDayOfMonth (dt), tokLen == 1 ? 1 : 2);
					else if (tokLen == 3)
						result.Append (dfi.GetAbbreviatedDayName (dfi.Calendar.GetDayOfWeek (dt)));
					else
						result.Append (dfi.GetDayName (dfi.Calendar.GetDayOfWeek (dt)));

					break;
				case 'M':
					// Month.m(m?) = month # (with leading 0 if two mm)
					// mmm = 3 letter name
					// mmmm+ = full name
					tokLen = DateTimeUtils.CountRepeat (format, i, ch);
					int month = dfi.Calendar.GetMonth(dt);
					if (tokLen <= 2)
						DateTimeUtils.ZeroPad (result, month, tokLen);
					else if (tokLen == 3)
						result.Append (dfi.GetAbbreviatedMonthName (month));
					else
						result.Append (dfi.GetMonthName (month));

					break;
				case 'y':
					// Year. y(y?) = two digit year, with leading 0 if yy
					// yyy+ full year with leading zeros if needed.
					tokLen = DateTimeUtils.CountRepeat (format, i, ch);

					if (tokLen <= 2)
						DateTimeUtils.ZeroPad (result, dfi.Calendar.GetYear (dt) % 100, tokLen);
					else
						DateTimeUtils.ZeroPad (result, dfi.Calendar.GetYear (dt), tokLen);
					break;

				case 'g':
					// Era name
					tokLen = DateTimeUtils.CountRepeat (format, i, ch);
					result.Append (dfi.GetEraName (dfi.Calendar.GetEra (dt)));
					break;

				//
				// Other
				//
				case ':':
					result.Append (dfi.TimeSeparator);
					tokLen = 1;
					break;
				case '/':
					result.Append (dfi.DateSeparator);
					tokLen = 1;
					break;
				case '\'': case '"':
					tokLen = DateTimeUtils.ParseQuotedString (format, i, result);
					break;
				case '%':
					if (i >= format.Length - 1)
						throw new FormatException ("% at end of date time string");
					if (format [i + 1] == '%')
						throw new FormatException ("%% in date string");

					// Look for the next char
					tokLen = 1;
					break;
				case '\\':
					// C-Style escape
					if (i >= format.Length - 1)
						throw new FormatException ("\\ at end of date time string");

					result.Append (format [i + 1]);
					tokLen = 2;

					break;
				default:
					// catch all
					result.Append (ch);
					tokLen = 1;
					break;
				}
				i += tokLen;
			}
			return result.ToString ();
		}
        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();
        }
 public void GetEraName(DateTimeFormatInfo format, int era, string expected)
 {
     Assert.Equal(expected, format.GetEraName(era));
 }
		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();
		}
	// Parse an era name.
	private static int ParseEra(String s, ref int posn,
								Calendar calendar, DateTimeFormatInfo info)
			{
				// Get the list of eras from the calendar.
				int[] eras = calendar.Eras;

				// Convert the eras into era names.
				String[] eraNames = new String [eras.Length];
				int index;
				for(index = 0; index < eras.Length; ++index)
				{
					eraNames[index] = info.GetEraName(eras[index]);
				}

				// Parse the era value using the strings we just got.
				return ParseOneOf(s, ref posn, eraNames);
			}
        //
        //  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());
        }
Exemple #14
0
        /*=================================MatchEraName==================================
        **Action: Parse era name from string starting at str.Index.
        **Returns: An era value. 
        **Arguments:    str: a __DTString.  The parsing will start from the
        **              next character after str.Index.
        **Exceptions: FormatException if an era name can not be found.
        ==============================================================================*/

        private static bool MatchEraName(__DTString str, DateTimeFormatInfo dtfi, bool isThrowExp, ref int result) {
            if (str.GetNext()) {
                int[] eras = dtfi.Calendar.Eras;

                if (eras != null) {
                    for (int i = 0; i <= eras.Length; i++) {
                        String searchStr = dtfi.GetEraName(eras[i]);
                        if (str.MatchSpecifiedWord(searchStr)) {
                            str.Index += (searchStr.Length - 1);
                            result = eras[i];
                            return (true);
                        }
                        searchStr = dtfi.GetAbbreviatedEraName(eras[i]);
                        if (str.MatchSpecifiedWord(searchStr)) {
                            str.Index += (searchStr.Length - 1);
                            result = eras[i];
                            return (true);
                        }
                    }
                }
            }
            return (ParseFormatError(isThrowExp, "Format_BadDateTime"));
        }
Exemple #15
0
        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':
                        tokenLen = ParseRepeatPattern(format, i, ch);
                        if (tokenLen <= MaxSecondsFractionDigits) {
                            long fraction = (dateTime.Ticks % Calendar.TicksPerSecond);
                            fraction = fraction / (long)Math.Pow(10, 7 - tokenLen);
                            result.Append(((int)fraction).ToString((new String('0', tokenLen))));
                        } 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 {             
                                result.Append(FormatMonth(month, tokenLen, dtfi));
                            }
                        }
                        bTimeOnly = false;
                        break;
                    case 'y':
                        int year = cal.GetYear(dateTime);
                        tokenLen = ParseRepeatPattern(format, i, ch);
                        switch (cal.ID) {
                            // Add a special case for Japanese.  
                            // For Japanese calendar, always use two digit (with leading 0)
                            case (Calendar.CAL_JAPAN):
                                FormatDigits(result, year, 2);
                                break;
                            case (Calendar.CAL_HEBREW):
                                HebrewFormatDigits(result, year);
                                break;
                            default:
                                if (tokenLen <= 2) {
                                    FormatDigits(result, year % 100, tokenLen);
                                } else {
                                    String fmtPattern = "D" + tokenLen;
                                    result.Append(year.ToString(fmtPattern));
                                }
                                break;
                        }
                        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 {
                            offset = TimeZone.CurrentTimeZone.GetUtcOffset(dateTime);
                        }
    
                        switch (tokenLen)
                        {
                            case 1:
                                result.Append((offset.Hours).ToString("+0;-0"));
                                break;
                            case 2:
                                result.Append((offset.Hours).ToString("+00;-00"));
                                break;
                            default:
                                if (offset.Hours > 0) {
                                    result.Append(String.Format("+{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("-{0:00}:{1:00}", -offset.Hours, -offset.Minutes));
                                }
                                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 '\\':
                        // 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 (result.ToString());
        }