/// <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 }
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")); }
internal static Exception TryParse(string s, out XsdDuration result) { return(TryParse(s, DurationType.Duration, out result)); }