/// <summary>
 ///		Converts specified <see cref="String"/> representation of a msgpack timestamp to its <see cref="Timestamp"/> equivalant
 ///		with specified format, culture-specific format information provider, and <see cref="DateTimeStyles"/>.
 /// </summary>
 /// <param name="input">An input <see cref="String"/> representation of a msgpack timestamp. The format must be match exactly to the <paramref name="format"/>.</param>
 /// <param name="format">An expected format string.</param>
 /// <param name="formatProvider">An <see cref="IFormatProvider"/> to provide culture specific information to parse <paramref name="input"/>.</param>
 /// <param name="styles">
 ///		Specify bitwise value combination of <see cref="DateTimeStyles"/> to control detailed parsing behavior.
 ///		The typical value is <see cref="DateTimeStyles.None"/>.
 /// </param>
 /// <param name="result">If the conversion succeeded, the conversion result will be stored; otherwise, the default value will be stored.</param>
 /// <returns><c>true</c>, if the conversion succeeded; otherwise, <c>false</c>.</returns>
 /// <remarks>
 ///		<para>
 ///			Currently, supported date-time format is only 'o' and 'O' (round-trip) or 's' (sortable, ISO-8601).
 ///			Other any standard date-time formats and custom date-time formats are not supported.
 ///		</para>
 ///		<para>
 ///			The rount-trip format is <c>yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffff'Z'</c> which "fffffffff" is nanoseconds.
 ///		</para>
 ///		<para>
 ///			The sign mark can be culture-specific, and leading/trailing whitespaces can be allowed when specify appropriate <see cref="DateTimeStyles"/>.
 ///		</para>
 /// </remarks>
 /// <exception cref="ArgumentNullException">
 ///		<paramref name="input"/> is <c>null</c>.
 ///		Or, <paramref name="format"/> is <c>null</c>.
 /// </exception>
 /// <exception cref="ArgumentException">
 ///		The specified <paramref name="format"/> is not supported.
 ///		Or the specified <paramref name="styles"/> has invalid combination.
 /// </exception>
 public static bool TryParseExact(string input, string format, IFormatProvider formatProvider, DateTimeStyles styles, out Timestamp result)
 {
     return(TryParseExactCore(input, format, formatProvider, styles, out result) == TimestampParseResult.Success);
 }
        private static TimestampParseResult TryParseExactCore(string input, string format, IFormatProvider formatProvider, DateTimeStyles styles, out Timestamp result)
        {
            ValidateParseInput(input);

            if (input.Length == 0)
            {
                result = default(Timestamp);
                return(TimestampParseResult.EmptyInput);
            }

            if (format == null)
            {
                throw new ArgumentNullException("format");
            }

            if (format.Length == 0)
            {
                throw new ArgumentException("The 'format' must not be empty.", "format");
            }

            ValidateParseStyles(styles);

            var error = TimestampStringConverter.TryParseExact(input, format, formatProvider, styles, out result);

            if (error == TimestampParseResult.UnsupportedFormat)
            {
                // UnsupportedFormat should throw Exception instead of returning false.
                HandleParseResult(error, "Cannot parse specified input with specified format.");
            }

            return(error);
        }
        private static TimestampParseResult TryParseExactCore(string input, string[] formats, IFormatProvider formatProvider, DateTimeStyles styles, out Timestamp result)
        {
            ValidateParseInput(input);

            if (formats == null)
            {
                throw new ArgumentNullException("formats");
            }

            if (formats.Length == 0)
            {
                throw new ArgumentException("The 'formats' must not be empty.", "formats");
            }

            ValidateParseStyles(styles);

            if (input.Length == 0)
            {
                result = default(Timestamp);
                return(TimestampParseResult.EmptyInput);
            }

            foreach (var format in formats)
            {
                if (TimestampStringConverter.TryParseExact(input, format, formatProvider, styles, out result) == TimestampParseResult.Success)
                {
                    return(TimestampParseResult.Success);
                }
            }

            result = default(Timestamp);
            return(TimestampParseResult.NoMatchedFormats);
        }
Пример #4
0
        // Currently, custom format and normal date time format except 'o' or 'O' 's' are NOT supported.
        public static TimestampParseResult TryParseExact(string input, string format, IFormatProvider formatProvider, DateTimeStyles styles, out Timestamp result)
        {
            if (format != "o" && format != "O" && format != "s")
            {
                result = default(Timestamp);
                return(TimestampParseResult.UnsupportedFormat);
            }

            var numberFormat = NumberFormatInfo.GetInstance(formatProvider);

            var position = 0;

            if (!ParseWhitespace(input, ref position, (styles & DateTimeStyles.AllowLeadingWhite) != 0, /* isTrailing */ false))
            {
                result = default(Timestamp);
                return(TimestampParseResult.LeadingWhitespaceNotAllowed);
            }

            long year;

            if (!ParseYear(input, ref position, numberFormat, out year))
            {
                result = default(Timestamp);
                return(TimestampParseResult.InvalidYear);
            }

            if (!ParseDelimiter(input, ref position, DateDelimiter))
            {
                result = default(Timestamp);
                return(TimestampParseResult.InvalidYearMonthDeilimiter);
            }

            var isLeapYear = Timestamp.IsLeapYearInternal(year);

            int month;

            if (!ParseDigitRange(input, 2, ref position, 1, 12, out month))
            {
                result = default(Timestamp);
                return(TimestampParseResult.InvalidMonth);
            }

            if (!ParseDelimiter(input, ref position, DateDelimiter))
            {
                result = default(Timestamp);
                return(TimestampParseResult.InvalidMonthDayDelimiter);
            }

            int day;

            if (!ParseDay(input, ref position, month, isLeapYear, out day))
            {
                result = default(Timestamp);
                return(TimestampParseResult.InvalidDay);
            }

            if (!ParseDelimiter(input, ref position, DateTimeDelimiter))
            {
                result = default(Timestamp);
                return(TimestampParseResult.InvalidDateTimeDelimiter);
            }

            int hour;

            if (!ParseDigitRange(input, 2, ref position, 0, 23, out hour))
            {
                result = default(Timestamp);
                return(TimestampParseResult.InvalidHour);
            }

            if (!ParseDelimiter(input, ref position, TimeDelimiter))
            {
                result = default(Timestamp);
                return(TimestampParseResult.InvalidHourMinuteDelimiter);
            }

            int minute;

            if (!ParseDigitRange(input, 2, ref position, 0, 59, out minute))
            {
                result = default(Timestamp);
                return(TimestampParseResult.InvalidMinute);
            }

            if (!ParseDelimiter(input, ref position, TimeDelimiter))
            {
                result = default(Timestamp);
                return(TimestampParseResult.InvalidMinuteSecondDelimiter);
            }

            int second;

            if (!ParseDigitRange(input, 2, ref position, 0, 59, out second))
            {
                result = default(Timestamp);
                return(TimestampParseResult.InvalidSecond);
            }

            var nanosecond = 0;

            if (format != "s")
            {
                // "o" or "O"
                if (!ParseDelimiter(input, ref position, SubsecondDelimiter))
                {
                    result = default(Timestamp);
                    return(TimestampParseResult.InvalidSubsecondDelimiter);
                }

                if (!ParseDigitRange(input, 9, ref position, 0, 999999999, out nanosecond))
                {
                    result = default(Timestamp);
                    return(TimestampParseResult.InvalidNanoSecond);
                }
            }

            if (!ParseDelimiter(input, ref position, UtcSign))
            {
                result = default(Timestamp);
                return(TimestampParseResult.MissingUtcSign);
            }

            if (!ParseWhitespace(input, ref position, (styles & DateTimeStyles.AllowTrailingWhite) != 0, /* isTrailing */ true))
            {
                result = default(Timestamp);
                return(TimestampParseResult.TrailingWhitespaceNotAllowed);
            }

            if (position != input.Length)
            {
                result = default(Timestamp);
                return(TimestampParseResult.ExtraCharactors);
            }

            var components = new Timestamp.Value();

            components.Year        = year;
            components.Month       = month;
            components.Day         = day;
            components.Hour        = hour;
            components.Minute      = minute;
            components.Second      = second;
            components.Nanoseconds = unchecked (( uint )nanosecond);

            try
            {
                result = Timestamp.FromComponents(ref components, isLeapYear);
            }
            catch (OverflowException)
            {
                result = default(Timestamp);
                return(TimestampParseResult.YearOutOfRange);
            }

            return(TimestampParseResult.Success);
        }