Beispiel #1
0
        /// <summary>
        /// Construct an XsdDuration from a TimeSpan value that represents an xsd:duration, an xdt:dayTimeDuration, or
        /// an xdt:yearMonthDuration.
        /// </summary>
        internal XsdDuration(TimeSpan timeSpan, DurationType durationType)
        {
            long  ticks = timeSpan.Ticks;
            ulong ticksPos;
            bool  isNegative;

            if (ticks < 0)
            {
                // Note that (ulong) -Int64.MinValue = Int64.MaxValue + 1, which is what we want for that special case
                isNegative = true;
                ticksPos   = (ulong)-ticks;
            }
            else
            {
                isNegative = false;
                ticksPos   = (ulong)ticks;
            }

            if (durationType == DurationType.YearMonthDuration)
            {
                int years  = (int)(ticksPos / ((ulong)TimeSpan.TicksPerDay * 365));
                int months = (int)((ticksPos % ((ulong)TimeSpan.TicksPerDay * 365)) / ((ulong)TimeSpan.TicksPerDay * 30));

                if (months == 12)
                {
                    // If remaining days >= 360 and < 365, then round off to year
                    years++;
                    months = 0;
                }

                this = new XsdDuration(isNegative, years, months, 0, 0, 0, 0, 0);
            }
            else
            {
                Debug.Assert(durationType == DurationType.Duration || durationType == DurationType.DayTimeDuration);

                // Tick count is expressed in 100 nanosecond intervals
                this.nanoseconds = (uint)(ticksPos % 10000000) * 100;
                if (isNegative)
                {
                    this.nanoseconds |= NegativeBit;
                }

                this.years   = 0;
                this.months  = 0;
                this.days    = (int)(ticksPos / (ulong)TimeSpan.TicksPerDay);
                this.hours   = (int)((ticksPos / (ulong)TimeSpan.TicksPerHour) % 24);
                this.minutes = (int)((ticksPos / (ulong)TimeSpan.TicksPerMinute) % 60);
                this.seconds = (int)((ticksPos / (ulong)TimeSpan.TicksPerSecond) % 60);
            }
        }
        public static TimeSpan ParseXsdTimeSpan(string dateTimeStr)
        {
#if    PLATFORM_USE_XML_DLL
            return(XmlConvert.ToTimeSpan(dateTimeStr));
#else
            //return  ManulParseXsdTimeSpan(dateTimeStr );



            XsdDuration duration = new XsdDuration(dateTimeStr);

            return(duration.ToTimeSpan());
#endif
        }
        public static string ToXsdTimeSpanString(TimeSpan timeSpan)
        {
#if    PLATFORM_USE_XML_DLL
            var r = XmlConvert.ToString(timeSpan);
#if __MonoCS__
            // Mono returns DT even if time is 00:00:00
            if (r.EndsWith("DT"))
            {
                return(r.Substring(0, r.Length - 1));
            }
#endif
            return(r);
#else
            XsdDuration duration = new XsdDuration(timeSpan);

            return(duration.ToString( ));
#endif
        }
        public static TimeSpan?ParseXsdNullableTimeSpan(string dateTimeStr)
        {
#if    PLATFORM_USE_XML_DLL
            return(String.IsNullOrEmpty(dateTimeStr) ?
                   null :
                   new TimeSpan?(XmlConvert.ToTimeSpan(dateTimeStr)));
#else
            if (String.IsNullOrEmpty(dateTimeStr))
            {
                return(null);
            }

            //return  ManulParseXsdTimeSpan(dateTimeStr );

            XsdDuration duration = new XsdDuration(dateTimeStr);

            return(duration.ToTimeSpan());
#endif
        }
Beispiel #5
0
        internal static Exception TryParse(string s, DurationType durationType, out XsdDuration result)
        {
            string errorCode;
            int    length;
            int    value, pos, numDigits;
            Parts  parts = Parts.HasNone;

            result = new XsdDuration();

            s      = s.Trim();
            length = s.Length;

            pos       = 0;
            numDigits = 0;

            if (pos >= length)
            {
                goto InvalidFormat;
            }

            if (s[pos] == '-')
            {
                pos++;
                result.nanoseconds = NegativeBit;
            }
            else
            {
                result.nanoseconds = 0;
            }

            if (pos >= length)
            {
                goto InvalidFormat;
            }

            if (s[pos++] != 'P')
            {
                goto InvalidFormat;
            }

            errorCode = TryParseDigits(s, ref pos, false, out value, out numDigits);
            if (errorCode != null)
            {
                goto Error;
            }

            if (pos >= length)
            {
                goto InvalidFormat;
            }

            if (s[pos] == 'Y')
            {
                if (numDigits == 0)
                {
                    goto InvalidFormat;
                }

                parts       |= Parts.HasYears;
                result.years = value;
                if (++pos == length)
                {
                    goto Done;
                }

                errorCode = TryParseDigits(s, ref pos, false, out value, out numDigits);
                if (errorCode != null)
                {
                    goto Error;
                }

                if (pos >= length)
                {
                    goto InvalidFormat;
                }
            }

            if (s[pos] == 'M')
            {
                if (numDigits == 0)
                {
                    goto InvalidFormat;
                }

                parts        |= Parts.HasMonths;
                result.months = value;
                if (++pos == length)
                {
                    goto Done;
                }

                errorCode = TryParseDigits(s, ref pos, false, out value, out numDigits);
                if (errorCode != null)
                {
                    goto Error;
                }

                if (pos >= length)
                {
                    goto InvalidFormat;
                }
            }

            if (s[pos] == 'D')
            {
                if (numDigits == 0)
                {
                    goto InvalidFormat;
                }

                parts      |= Parts.HasDays;
                result.days = value;
                if (++pos == length)
                {
                    goto Done;
                }

                errorCode = TryParseDigits(s, ref pos, false, out value, out numDigits);
                if (errorCode != null)
                {
                    goto Error;
                }

                if (pos >= length)
                {
                    goto InvalidFormat;
                }
            }

            if (s[pos] == 'T')
            {
                if (numDigits != 0)
                {
                    goto InvalidFormat;
                }

                pos++;
                errorCode = TryParseDigits(s, ref pos, false, out value, out numDigits);
                if (errorCode != null)
                {
                    goto Error;
                }

                if (pos >= length)
                {
                    goto InvalidFormat;
                }

                if (s[pos] == 'H')
                {
                    if (numDigits == 0)
                    {
                        goto InvalidFormat;
                    }

                    parts       |= Parts.HasHours;
                    result.hours = value;
                    if (++pos == length)
                    {
                        goto Done;
                    }

                    errorCode = TryParseDigits(s, ref pos, false, out value, out numDigits);
                    if (errorCode != null)
                    {
                        goto Error;
                    }

                    if (pos >= length)
                    {
                        goto InvalidFormat;
                    }
                }

                if (s[pos] == 'M')
                {
                    if (numDigits == 0)
                    {
                        goto InvalidFormat;
                    }

                    parts         |= Parts.HasMinutes;
                    result.minutes = value;
                    if (++pos == length)
                    {
                        goto Done;
                    }

                    errorCode = TryParseDigits(s, ref pos, false, out value, out numDigits);
                    if (errorCode != null)
                    {
                        goto Error;
                    }

                    if (pos >= length)
                    {
                        goto InvalidFormat;
                    }
                }

                if (s[pos] == '.')
                {
                    pos++;

                    parts         |= Parts.HasSeconds;
                    result.seconds = value;

                    errorCode = TryParseDigits(s, ref pos, true, out value, out numDigits);
                    if (errorCode != null)
                    {
                        goto Error;
                    }

                    if (numDigits == 0)   //If there are no digits after the decimal point, assume 0
                    {
                        value = 0;
                    }
                    // Normalize to nanosecond intervals
                    for (; numDigits > 9; numDigits--)
                    {
                        value /= 10;
                    }

                    for (; numDigits < 9; numDigits++)
                    {
                        value *= 10;
                    }

                    result.nanoseconds |= (uint)value;

                    if (pos >= length)
                    {
                        goto InvalidFormat;
                    }

                    if (s[pos] != 'S')
                    {
                        goto InvalidFormat;
                    }
                    if (++pos == length)
                    {
                        goto Done;
                    }
                }
                else if (s[pos] == 'S')
                {
                    if (numDigits == 0)
                    {
                        goto InvalidFormat;
                    }

                    parts         |= Parts.HasSeconds;
                    result.seconds = value;
                    if (++pos == length)
                    {
                        goto Done;
                    }
                }
            }

            // Duration cannot end with digits
            if (numDigits != 0)
            {
                goto InvalidFormat;
            }

            // No further characters are allowed
            if (pos != length)
            {
                goto InvalidFormat;
            }

Done:
            // At least one part must be defined
            if (parts == Parts.HasNone)
            {
                goto InvalidFormat;
            }

            if (durationType == DurationType.DayTimeDuration)
            {
                if ((parts & (Parts.HasYears | Parts.HasMonths)) != 0)
                {
                    goto InvalidFormat;
                }
            }
            else if (durationType == DurationType.YearMonthDuration)
            {
                if ((parts & ~(XsdDuration.Parts.HasYears | XsdDuration.Parts.HasMonths)) != 0)
                {
                    goto InvalidFormat;
                }
            }
            return(null);

InvalidFormat:
            //return new FormatException(Res.GetString(Res.XmlConvert_BadFormat, s, durationType));


            return(new FormatException("XmlConvert_BadFormat"));

Error:
            //return new OverflowException(Res.GetString(Res.XmlConvert_Overflow, s, durationType));

            return(new OverflowException("XmlConvert_Overflow"));
        }
Beispiel #6
0
 internal static Exception TryParse(string s, out XsdDuration result)
 {
     return(TryParse(s, DurationType.Duration, out result));
 }