public static CalendarDateTime Subtract(CalendarDateTime x, CalendarDateTimeDuration y) { long year = x.Year - y.Years; double month = x.Month - y.Months; double day = x.Day - y.Days; double hour = x.Hour - y.Hours; double minute = x.Minute; double second = x.Second; TimePrecision precision = x.Precision; if (y.Minutes != null) { minute -= y.Minutes.Value; if (minute != (int)minute && precision > TimePrecision.Minute) { second += (minute - (int)minute) * SecondsPerMinute; minute = (int)minute; } if (precision < TimePrecision.Minute) { precision = TimePrecision.Minute; } } if (y.Seconds != null) { second -= y.Seconds.Value; if (precision < TimePrecision.Second) { precision = TimePrecision.Second; } } while (second <= -SecondsPerMinute) { second += SecondsPerMinute; minute--; } while (minute <= -MinutesPerHour) { minute += MinutesPerHour; hour--; } while (hour <= -HoursPerDay) { hour += HoursPerDay; day--; } while (month < 1) { month += MonthsPerYear; year--; } while (day < 1) { day += DaysInMonth(year, (int)month); month--; } switch (precision) { case TimePrecision.Hour: return new CalendarDateTime(new CalendarDate(year, (int)month, (int)day), new Time(hour)); case TimePrecision.Minute: return new CalendarDateTime(new CalendarDate(year, (int)month, (int)day), new Time((int)hour, minute)); case TimePrecision.Second: return new CalendarDateTime(new CalendarDate(year, (int)month, (int)day), new Time((int)hour, (int)minute, second)); default: return null; } }
public static CalendarDateTime Add(CalendarDateTime x, CalendarDateTimeDuration y) { double day = x.Day + y.Days; double month = x.Month + y.Months; double year = x.Year + y.Years; var second = x.Second; var minute = x.Minute; var hour = x.Hour + y.Hours; var precision = x.Precision; if (y.Minutes != null) { minute += y.Minutes.Value; if (hour != (int)hour) { minute += (hour - (int)hour) * MinutesPerHour; } if (precision < TimePrecision.Minute) { precision = TimePrecision.Minute; } } if (y.Seconds != null) { second += y.Seconds.Value; if (minute != (int)minute) { second += (minute - (int)minute) * SecondsPerMinute; } if (precision < TimePrecision.Second) { precision = TimePrecision.Second; } } while (!(second < SecondsPerMinute)) { second -= SecondsPerMinute; minute++; } while ((int)minute >= MinutesPerHour) { minute -= MinutesPerHour; hour++; } while ((int)hour >= HoursPerDay) { hour -= HoursPerDay; day++; } while ((int)month > MonthsPerYear) { month -= MonthsPerYear; year++; } int daysInMonth = DaysInMonth((long)year, (int)month); while (day > daysInMonth) { day -= daysInMonth; month++; daysInMonth = DaysInMonth((long)year, (int)month); } switch (precision) { case TimePrecision.Hour: return new CalendarDateTime(new CalendarDate((long)year, (int)month, (int)day), new Time(hour)); case TimePrecision.Minute: return new CalendarDateTime(new CalendarDate((long)year, (int)month, (int)day), new Time((int)hour, minute)); case TimePrecision.Second: return new CalendarDateTime(new CalendarDate((long)year, (int)month, (int)day), new Time((int)hour, (int)minute, second)); default: return null; } }