internal static Iso8601Duration Normalise(Iso8601Duration duration) { Check.Require(duration != null, "duration must not be null."); int seconds = duration.Seconds; int minutes = duration.Minutes; int hours = duration.Hours; int days = duration.Days + duration.Weeks * 7; int months = duration.Months; int years = duration.Years; if (seconds >= 60) { minutes += seconds / 60; seconds = seconds % 60; } if (minutes >= 60) { hours += minutes / 60; minutes = minutes % 60; } if (hours >= 24) { days += hours / 24; hours = hours % 24; } if (months > 12) { years += months / 12; months = months % 12; } return(new Iso8601Duration(years, months, days, 0, hours, minutes, seconds, duration.FractionalSecond)); }
internal Iso8601Time Add(Iso8601Duration duration) { DesignByContract.Check.Require(duration != null, "duration must not be null."); Iso8601Time newTime = new Iso8601Time(this.ToString()); Iso8601Duration normalisedDuration = Iso8601Duration.Normalise(duration); if (normalisedDuration.FractionalSecond > 0) { if (newTime.SecondUnknown) { throw new NotSupportedException("Cannot add a duration with fractionalSeconds when the datetime seconds unknow."); } if (newTime.HasFractionalSecond) { newTime.fractionalSecond += normalisedDuration.FractionalSecond; NormaliseFractionalSecond(newTime); } else { newTime.fractionalSecond = normalisedDuration.FractionalSecond; } } if (normalisedDuration.Seconds > 0) { if (newTime.SecondUnknown) { throw new NotSupportedException("Cannot add a duration with seconds when the time seconds unknow."); } newTime.second += normalisedDuration.Seconds; NormaliseSecond(newTime); } if (normalisedDuration.Minutes > 0) { if (newTime.MinuteUnknown) { throw new NotSupportedException("Cannot add a duration with minutes when the time minutes unknow."); } newTime.minute += normalisedDuration.Minutes; NormaliseMinute(newTime); } if (normalisedDuration.Hours > 0) { newTime.hour += normalisedDuration.Hours; if (newTime.hour >= 24) { throw new ApplicationException("Invalid durtion results in the hours value greater or equal to 24."); } } return(newTime); }
internal static Iso8601Duration NormaliseDuration(int yearsDiff, int monthsDiff, int weeksDiff, int daysDiff, int hoursDiff, int minutesDiff, int secondsDiff, double fractionalSecondsDiff, int daysInMonth) { if (fractionalSecondsDiff < 0) { fractionalSecondsDiff += 1; secondsDiff -= 1; } if (secondsDiff < 0) { secondsDiff += Iso8601DateTime.secondsInMinute; minutesDiff--; } if (minutesDiff < 0) { minutesDiff += Iso8601DateTime.minutesInHour; hoursDiff--; } if (hoursDiff < 0) { hoursDiff += Iso8601DateTime.hoursInDay; daysDiff--; } if (daysDiff < 0) { daysDiff += daysInMonth; monthsDiff--; } if (monthsDiff < 0) { monthsDiff += Iso8601DateTime.monthsInYear; if (yearsDiff <= 0) { throw new ApplicationException("yearsDiff must greater than 1."); } yearsDiff--; } if (daysDiff > 0 && daysDiff % Iso8601DateTime.daysInWeek == 0) { weeksDiff = daysDiff / Iso8601DateTime.daysInWeek; daysDiff = 0; } Iso8601Duration diff = new Iso8601Duration(yearsDiff, monthsDiff, daysDiff, weeksDiff, hoursDiff, minutesDiff, secondsDiff, fractionalSecondsDiff); return(diff); }
internal Iso8601Date Subtract(Iso8601Duration duration) { DesignByContract.Check.Require(duration != null, "duration must not be null."); Iso8601Date newDate = new Iso8601Date(this.ToString()); Iso8601Duration normalisedDuration = Iso8601Duration.Normalise(duration); if (normalisedDuration.Days > 0) { if (newDate.DayUnknown) { throw new NotSupportedException("Cannot subtract a duration with days when the datetime day unknow."); } newDate.day -= normalisedDuration.Days; NormaliseSubtractedDay(newDate); } if (normalisedDuration.Months > 0) { if (newDate.MonthUnknown) { throw new NotSupportedException("Cannot subtract a duration with months when the datetime month unknow."); } newDate.month -= normalisedDuration.Months; NormaliseSubtractedMonth(newDate); if (!newDate.DayUnknown && (newDate.day > System.DateTime.DaysInMonth(newDate.year, newDate.month))) { newDate.day = System.DateTime.DaysInMonth(newDate.year, newDate.month); } } if (normalisedDuration.Years > 0) { if (normalisedDuration.Years > newDate.year) { throw new ApplicationException("duration.Years must not greater than the dateTime.year"); } newDate.year -= normalisedDuration.Years; } return(newDate); }
internal Iso8601Date Add(Iso8601Duration duration) { DesignByContract.Check.Require(duration != null, "duration must not be null."); Iso8601Date newDate = new Iso8601Date(this.ToString()); Iso8601Duration normalisedDuration = Iso8601Duration.Normalise(duration); if (normalisedDuration.Months > 0) { if (newDate.MonthUnknown) { throw new NotSupportedException("Cannot add a duration with months when the datetime month unknow."); } newDate.month += normalisedDuration.Months; NormaliseMonth(newDate); if (normalisedDuration.Days <= 0) { if (!newDate.DayUnknown && newDate.day > System.DateTime.DaysInMonth(newDate.year, newDate.month)) { newDate.day = System.DateTime.DaysInMonth(newDate.year, newDate.month); } } } if (normalisedDuration.Years > 0) { newDate.year += normalisedDuration.Years; } if (normalisedDuration.Days > 0) { if (newDate.DayUnknown) { throw new NotSupportedException("Cannot add a duration with days when the datetime day unknow."); } newDate.day += normalisedDuration.Days; NormaliseDay(newDate); } return(newDate); }
/// <summary> /// Compare the current date time instance with the obj. Returns 0 if they are equal, /// -1 if the current instance less than obj, 1 if the current instance greater than obj. /// </summary> /// <param name="obj"></param> /// <returns></returns> public int CompareTo(object obj) { // precondition is that the current instance must be the same type as obj Check.Require(this.GetType() == obj.GetType(), "The current instance (" + this.GetType().ToString() + ") must be the same type as the obj(" + obj.GetType().ToString() + ")"); Iso8601Duration objDuration = obj as Iso8601Duration; if (this.durationValueInSeconds < objDuration.durationValueInSeconds) { return(-1); } else if (this.durationValueInSeconds == objDuration.durationValueInSeconds) { return(0); } else { return(1); } }
internal Iso8601Time Subtract(Iso8601Duration duration) { DesignByContract.Check.Require(duration != null, "duration must not be null."); Iso8601Time newTime = new Iso8601Time(this.ToString()); Iso8601Duration normalisedDuration = Iso8601Duration.Normalise(duration); if (normalisedDuration.FractionalSecond > 0) { if (newTime.SecondUnknown) throw new NotSupportedException("Cannot subtract a duration with fractionalSeconds when the time seconds unknow."); if (newTime.HasFractionalSecond) newTime.fractionalSecond -= normalisedDuration.FractionalSecond; else newTime.fractionalSecond = (normalisedDuration.FractionalSecond)*-1; NormaliseSubtractedFractionalSecond(newTime); } if (normalisedDuration.Seconds > 0) { if (newTime.SecondUnknown) throw new NotSupportedException("Cannot subtract a duration with seconds when the time seconds unknow."); newTime.second -= normalisedDuration.Seconds; NormaliseSubtractedSecond(newTime); } if (normalisedDuration.Minutes > 0) { if (newTime.MinuteUnknown) throw new NotSupportedException("Cannot subtract a duration with minutes when the time minutes unknow."); newTime.minute -= normalisedDuration.Minutes; NormaliseSubtractedMinute(newTime); } if (normalisedDuration.Hours > 0) { newTime.hour -= normalisedDuration.Hours; if (newTime.hour < 0) throw new ApplicationException("Invalid duration results the Iso8601Time hour less than 0 after subtraction."); } return newTime; }
internal Iso8601Time Add(Iso8601Duration duration) { DesignByContract.Check.Require(duration != null, "duration must not be null."); Iso8601Time newTime = new Iso8601Time(this.ToString()); Iso8601Duration normalisedDuration = Iso8601Duration.Normalise(duration); if (normalisedDuration.FractionalSecond > 0) { if (newTime.SecondUnknown) throw new NotSupportedException("Cannot add a duration with fractionalSeconds when the datetime seconds unknow."); if (newTime.HasFractionalSecond) { newTime.fractionalSecond += normalisedDuration.FractionalSecond; NormaliseFractionalSecond(newTime); } else newTime.fractionalSecond = normalisedDuration.FractionalSecond; } if (normalisedDuration.Seconds > 0) { if (newTime.SecondUnknown) throw new NotSupportedException("Cannot add a duration with seconds when the time seconds unknow."); newTime.second += normalisedDuration.Seconds; NormaliseSecond(newTime); } if (normalisedDuration.Minutes > 0) { if (newTime.MinuteUnknown) throw new NotSupportedException("Cannot add a duration with minutes when the time minutes unknow."); newTime.minute += normalisedDuration.Minutes; NormaliseMinute(newTime); } if (normalisedDuration.Hours > 0) { newTime.hour += normalisedDuration.Hours; if (newTime.hour >= 24) throw new ApplicationException("Invalid durtion results in the hours value greater or equal to 24."); } return newTime; }
internal static Iso8601Duration NormaliseDuration(int yearsDiff, int monthsDiff, int weeksDiff, int daysDiff, int hoursDiff, int minutesDiff, int secondsDiff, double fractionalSecondsDiff, int daysInMonth) { if (fractionalSecondsDiff < 0) { fractionalSecondsDiff += 1; secondsDiff -= 1; } if (secondsDiff < 0) { secondsDiff += Iso8601DateTime.secondsInMinute; minutesDiff--; } if (minutesDiff < 0) { minutesDiff += Iso8601DateTime.minutesInHour; hoursDiff--; } if (hoursDiff < 0) { hoursDiff += Iso8601DateTime.hoursInDay; daysDiff--; } if (daysDiff < 0) { daysDiff += daysInMonth; monthsDiff--; } if (monthsDiff < 0) { monthsDiff += Iso8601DateTime.monthsInYear; if (yearsDiff <= 0) throw new ApplicationException("yearsDiff must greater than 1."); yearsDiff--; } if (daysDiff > 0 && daysDiff % Iso8601DateTime.daysInWeek == 0) { weeksDiff = daysDiff / Iso8601DateTime.daysInWeek; daysDiff = 0; } Iso8601Duration diff = new Iso8601Duration(yearsDiff, monthsDiff, daysDiff, weeksDiff, hoursDiff, minutesDiff, secondsDiff, fractionalSecondsDiff); return diff; }
internal Iso8601Date Subtract(Iso8601Duration duration) { DesignByContract.Check.Require(duration != null, "duration must not be null."); Iso8601Date newDate = new Iso8601Date(this.ToString()); Iso8601Duration normalisedDuration = Iso8601Duration.Normalise(duration); if (normalisedDuration.Days > 0) { if (newDate.DayUnknown) throw new NotSupportedException("Cannot subtract a duration with days when the datetime day unknow."); newDate.day -= normalisedDuration.Days; NormaliseSubtractedDay(newDate); } if (normalisedDuration.Months > 0) { if (newDate.MonthUnknown) throw new NotSupportedException("Cannot subtract a duration with months when the datetime month unknow."); newDate.month -= normalisedDuration.Months; NormaliseSubtractedMonth(newDate); if (!newDate.DayUnknown &&(newDate.day>System.DateTime.DaysInMonth(newDate.year, newDate.month))) { newDate.day = System.DateTime.DaysInMonth(newDate.year, newDate.month); } } if (normalisedDuration.Years > 0) { if (normalisedDuration.Years > newDate.year) throw new ApplicationException("duration.Years must not greater than the dateTime.year"); newDate.year -= normalisedDuration.Years; } return newDate; }
internal Iso8601Date Add(Iso8601Duration duration) { DesignByContract.Check.Require(duration != null, "duration must not be null."); Iso8601Date newDate = new Iso8601Date(this.ToString()); Iso8601Duration normalisedDuration = Iso8601Duration.Normalise(duration); if (normalisedDuration.Months > 0) { if (newDate.MonthUnknown) throw new NotSupportedException("Cannot add a duration with months when the datetime month unknow."); newDate.month += normalisedDuration.Months; NormaliseMonth(newDate); if (normalisedDuration.Days <= 0) { if (!newDate.DayUnknown && newDate.day > System.DateTime.DaysInMonth(newDate.year, newDate.month)) newDate.day = System.DateTime.DaysInMonth(newDate.year, newDate.month); } } if (normalisedDuration.Years > 0) newDate.year += normalisedDuration.Years; if (normalisedDuration.Days > 0) { if (newDate.DayUnknown) throw new NotSupportedException("Cannot add a duration with days when the datetime day unknow."); newDate.day += normalisedDuration.Days; NormaliseDay(newDate); } return newDate; }
private bool IsMatchPattern(Iso8601Duration isoDuration) { DesignByContract.Check.Require(isoDuration != null, string.Format(CommonStrings.XMustNotBeNull, "isoDuration")); if (this.yearsAllowedSet && !this.YearsAllowed && isoDuration.Years > 0) return false; if (this.monthsAllowedSet && !this.MonthsAllowed && isoDuration.Months > 0) return false; if (this.weeksAllowedSet && !this.WeeksAllowed && isoDuration.Weeks > 0) return false; if (this.daysAllowedSet && !this.DaysAllowed && isoDuration.Days > 0) return false; if (this.hoursAllowedSet && !this.HoursAllowed && isoDuration.Hours > 0) return false; if (this.minutesAllowedSet && !this.MinutesAllowed && isoDuration.Months > 0) return false; if (this.secondsAllowedSet && !this.SecondsAllowed && isoDuration.Seconds > 0) return false; if (!this.fractionalSecondsAllowed && isoDuration.FractionalSecond > 0) return false; return true; }
internal static Iso8601Duration Normalise(Iso8601Duration duration) { Check.Require(duration != null, "duration must not be null."); int seconds = duration.Seconds; int minutes = duration.Minutes; int hours = duration.Hours; int days = duration.Days + duration.Weeks *7; int months = duration.Months; int years = duration.Years; if (seconds >= 60) { minutes += seconds / 60; seconds = seconds % 60; } if (minutes >= 60) { hours += minutes / 60; minutes = minutes % 60; } if (hours >= 24) { days += hours / 24; hours = hours % 24; } if (months > 12) { years += months / 12; months = months % 12; } return new Iso8601Duration(years, months, days, 0, hours, minutes, seconds, duration.FractionalSecond); }
internal Iso8601DateTime Subtract(Iso8601Duration duration) { DesignByContract.Check.Require(duration != null, "duration must not be null."); Iso8601DateTime newDateTime = new Iso8601DateTime(this.ToString()); Iso8601Duration normalisedDuration = Iso8601Duration.Normalise(duration); if (normalisedDuration.FractionalSecond > 0) { if (newDateTime.SecondUnknown) throw new NotSupportedException("Cannot subtract a duration with fractionalSeconds when the datetime seconds unknow."); if (newDateTime.HasFractionalSecond) newDateTime.fractionalSecond -= normalisedDuration.FractionalSecond; else newDateTime.fractionalSecond = (normalisedDuration.FractionalSecond) * -1; NormaliseSubtractedFractionalSecond(newDateTime); } if (normalisedDuration.Seconds > 0) { if (newDateTime.SecondUnknown) throw new NotSupportedException("Cannot subtract a duration with seconds when the datetime seconds unknow."); newDateTime.second -= normalisedDuration.Seconds; NormaliseSubtractedSecond(newDateTime); } if (normalisedDuration.Minutes > 0) { if (newDateTime.MinuteUnknown) throw new NotSupportedException("Cannot subtract a duration with minutes when the datetime minutes unknow."); newDateTime.minute -= normalisedDuration.Minutes; NormaliseSubtractedMinute(newDateTime); } if (normalisedDuration.Hours > 0) { if (newDateTime.HourUnknown) throw new NotSupportedException("Cannot subtract a duration with hours when the datetime hour unknow."); newDateTime.hour -= normalisedDuration.Hours; NormaliseSubtractedHour(newDateTime); } if (normalisedDuration.Days > 0) { if (newDateTime.DayUnknown) throw new NotSupportedException("Cannot subtract a duration with days when the datetime day unknow."); newDateTime.day -= normalisedDuration.Days; NormaliseSubtractedDay(newDateTime); } if (normalisedDuration.Months > 0) { if (newDateTime.MonthUnknown) throw new NotSupportedException("Cannot subtract a duration with months when the datetime month unknow."); newDateTime.month -= normalisedDuration.Months; NormaliseSubtractedMonth(newDateTime); if (!newDateTime.DayUnknown &&(newDateTime.day>System.DateTime.DaysInMonth(newDateTime.year, newDateTime.month))) { newDateTime.day = System.DateTime.DaysInMonth(newDateTime.year, newDateTime.month); } } if (normalisedDuration.Years > 0) { if (normalisedDuration.Years > newDateTime.year) throw new ApplicationException("duration.Years must not greater than the dateTime.year"); newDateTime.year -= normalisedDuration.Years; } return newDateTime; }
internal Iso8601DateTime Add(Iso8601Duration duration) { DesignByContract.Check.Require(duration != null, "duration must not be null."); Iso8601DateTime newDateTime = new Iso8601DateTime(this.ToString()); Iso8601Duration normalisedDuration = Iso8601Duration.Normalise(duration); if (normalisedDuration.FractionalSecond > 0) { if (newDateTime.SecondUnknown) throw new NotSupportedException("Cannot add a duration with fractionalSeconds when the datetime seconds unknow."); if (newDateTime.HasFractionalSecond) { newDateTime.fractionalSecond += normalisedDuration.FractionalSecond; NormaliseFractionalSecond(newDateTime); } else newDateTime.fractionalSecond = normalisedDuration.FractionalSecond; } if (normalisedDuration.Seconds > 0) { if (newDateTime.SecondUnknown) throw new NotSupportedException("Cannot add a duration with seconds when the datetime seconds unknow."); newDateTime.second += normalisedDuration.Seconds; NormaliseSecond(newDateTime); } if (normalisedDuration.Minutes > 0) { if (newDateTime.MinuteUnknown) throw new NotSupportedException("Cannot add a duration with minutes when the datetime minutes unknow."); newDateTime.minute += normalisedDuration.Minutes; NormaliseMinute(newDateTime); } if (normalisedDuration.Hours > 0) { if (newDateTime.HourUnknown) throw new NotSupportedException("Cannot add a duration with hours when the datetime hour unknow."); newDateTime.hour += normalisedDuration.Hours; NormaliseHour(newDateTime); NormaliseDay(newDateTime); } if (normalisedDuration.Months > 0) { if (newDateTime.MonthUnknown) throw new NotSupportedException("Cannot add a duration with months when the datetime month unknow."); newDateTime.month += normalisedDuration.Months; NormaliseMonth(newDateTime); if (normalisedDuration.Days <= 0) { if (!newDateTime.DayUnknown && (newDateTime.day > System.DateTime.DaysInMonth(newDateTime.year, newDateTime.month))) { newDateTime.day = System.DateTime.DaysInMonth(newDateTime.year, newDateTime.month); } } } if (normalisedDuration.Years > 0) newDateTime.year += normalisedDuration.Years; if (normalisedDuration.Days > 0) { if (newDateTime.DayUnknown) throw new NotSupportedException("Cannot add a duration with days when the datetime day unknow."); newDateTime.day += normalisedDuration.Days; NormaliseDay(newDateTime); } return newDateTime; }
internal Iso8601Time Subtract(Iso8601Duration duration) { DesignByContract.Check.Require(duration != null, "duration must not be null."); Iso8601Time newTime = new Iso8601Time(this.ToString()); Iso8601Duration normalisedDuration = Iso8601Duration.Normalise(duration); if (normalisedDuration.FractionalSecond > 0) { if (newTime.SecondUnknown) { throw new NotSupportedException("Cannot subtract a duration with fractionalSeconds when the time seconds unknow."); } if (newTime.HasFractionalSecond) { newTime.fractionalSecond -= normalisedDuration.FractionalSecond; } else { newTime.fractionalSecond = (normalisedDuration.FractionalSecond) * -1; } NormaliseSubtractedFractionalSecond(newTime); } if (normalisedDuration.Seconds > 0) { if (newTime.SecondUnknown) { throw new NotSupportedException("Cannot subtract a duration with seconds when the time seconds unknow."); } newTime.second -= normalisedDuration.Seconds; NormaliseSubtractedSecond(newTime); } if (normalisedDuration.Minutes > 0) { if (newTime.MinuteUnknown) { throw new NotSupportedException("Cannot subtract a duration with minutes when the time minutes unknow."); } newTime.minute -= normalisedDuration.Minutes; NormaliseSubtractedMinute(newTime); } if (normalisedDuration.Hours > 0) { newTime.hour -= normalisedDuration.Hours; if (newTime.hour < 0) { throw new ApplicationException("Invalid duration results the Iso8601Time hour less than 0 after subtraction."); } } return(newTime); }
internal override string ValidValue(object aValue) { DesignByContract.Check.Require(aValue != null, string.Format(CommonStrings.XMustNotBeNull, "aValue")); if (!Iso8601Duration.ValidIso8601Duration(aValue.ToString())) return string.Format(AmValidationStrings.InvalidIsoDurationX, aValue); Iso8601Duration isoDuration = new Iso8601Duration(aValue.ToString()); if (isoDuration == null) throw new ApplicationException(string.Format(CommonStrings.XIsNull, isoDuration)); if (this.Range != null) { if (!this.range.Has(isoDuration)) { return string.Format(AmValidationStrings.DurationXOutOfRange, aValue); } } if ( this.Range == null && this.Pattern == null) throw new ValidationException(CommonStrings.CDurationPatternAndRangeNull); if (this.range != null) { if(!IsMatchPattern(isoDuration)) { return string.Format(AmValidationStrings.DurationXDoesNotMatchPatternY, aValue, Pattern); } } return string.Empty; }