/// <summary> /// This method returns the end of the month that contains the given date. The method has not /// been designed to work if the dayShift is outside the range -30 to +30. /// </summary> /// <param name="date">the date whose month end is to be returned</param> /// <param name="dayShift">The shift (measured in days) in the definition of monthly time steps. /// If the value is 0, then months are defined as ending on the last day of the standard calendar /// month. If the value is 1, then months are defined as ending on the 1st day of the standard /// calendar month. If the value is -1, then months are defined as ending on the day before the /// last day of the standard calendar month.</param> public static DateTime RoundMonthEnd(this DateTime date, int dayShift) { DateTime endDate = new DateTime(date.Year, date.Month, 1).AddMinutes(-1).AddDays(dayShift); while (endDate < date) { endDate = endDate.AddMonthsByEnd(dayShift, 1); } return(endDate); }
/// <summary> /// This method computes the end date when given the start date, a regular time step size, /// and the number of time steps that should be added to the start date. /// </summary> /// <param name="startDate">The start date for the calculation</param> /// <param name="unit">Code for the time step units (e.g. hour, day, month...)</param> /// <param name="stepSize">The number of units per time step (e.g. Size=10 for 10-day time steps)</param> /// <param name="numSteps">The number of time steps to add to the start date</param> /// <returns>The end date of the calculation</returns> public static DateTime IncrementDate(DateTime startDate, TimeStepUnitCode unit, short stepSize, int numSteps) { DateTime calcDate; // The end date of the calculation DateTime date = startDate; // The DateTime class's various 'Add' methods lend themselves to // a switch statement so that whichever units the time step is measured in, // we can call the corresponding 'Add' method. switch (unit) { case TimeStepUnitCode.Minute: calcDate = date.AddMinutes(stepSize * numSteps); break; case TimeStepUnitCode.Hour: calcDate = date.AddHours(stepSize * numSteps); break; case TimeStepUnitCode.Day: calcDate = date.AddDays(stepSize * numSteps); break; case TimeStepUnitCode.Week: calcDate = date.AddDays(stepSize * numSteps * 7); break; case TimeStepUnitCode.Month: // For now, we only handle monthly time steps that end on regular calendar month // See https://github.com/hydrologics/Oasis/issues/163 date = date.RoundMonthEnd(0); calcDate = date.AddMonthsByEnd(0, stepSize * numSteps); break; case TimeStepUnitCode.Year: // For now, we only handle yearly time steps that end on regular calendar year // See https://github.com/hydrologics/Oasis/issues/163 date = new DateTime(date.Year + 1, 1, 1).AddMinutes(-1); calcDate = date.AddYears(stepSize * numSteps); break; default: calcDate = date; break; } return(calcDate); }
/// <summary> /// This method determines how many regular time steps are contained between the given /// start date and end date, when given a regular time step size. /// The method does not care whether the input start date comes before the input end /// date. It simply returns the absolute value of the number of steps between the given dates. /// Please note that the returned value is not inclusive of the first time step. That is, if the /// start date is 1/1 and the end date is 1/1, then the number of days between the given dates /// is returned as zero. /// </summary> /// <param name="startDate">The date when the count begins</param> /// <param name="endDate">The date when the count ends</param> /// <param name="unit">Code for the time step units (e.g. hour, day, month...)</param> /// <param name="stepSize">The number of units per time step (e.g. Size=10 for 10-day time steps)</param> /// <returns></returns> public static int CountSteps(DateTime startDate, DateTime endDate, TimeStepUnitCode unit, short stepSize) { DateTime calcDate; // Date value that will be iterated for the counting process int i = 0; // Counter for how many time steps // Method does not care whether the input start date comes before the input end // date. It simply returns the absolute value of the number of steps between the given dates. if (endDate < startDate) { calcDate = endDate; endDate = startDate; startDate = calcDate; } calcDate = startDate; // The DateTime class's various 'Add' methods lend themselves to // a switch statement so that whichever units the time step is measured in, // we can call the corresponding 'Add' method. The counting loop inside of // the switch statement is deliberately selected to be faster than a switch // statement inside of a loop. switch (unit) { case TimeStepUnitCode.Minute: for (i = 0; calcDate < endDate; i++) { calcDate = calcDate.AddMinutes(stepSize); } break; case TimeStepUnitCode.Hour: for (i = 0; calcDate < endDate; i++) { calcDate = calcDate.AddHours(stepSize); } break; case TimeStepUnitCode.Day: for (i = 0; calcDate < endDate; i++) { calcDate = calcDate.AddDays(stepSize); } break; case TimeStepUnitCode.Week: for (i = 0; calcDate < endDate; i++) { calcDate = calcDate.AddDays(stepSize * 7); } break; case TimeStepUnitCode.Month: // For now, we only handle monthly time steps that end on regular calendar month // See https://github.com/hydrologics/Oasis/issues/163 calcDate = RoundMonthEnd(calcDate, 0); for (i = 0; calcDate < endDate; i++) { calcDate = calcDate.AddMonthsByEnd(0, stepSize); } break; case TimeStepUnitCode.Year: // For now, we only handle yearly time steps that end on regular calendar year // See https://github.com/hydrologics/Oasis/issues/163 calcDate = new DateTime(calcDate.Year + 1, 1, 1).AddMinutes(-1); for (i = 0; calcDate < endDate; i++) { calcDate = calcDate.AddYears(stepSize); } break; } return(i); }
public void AddMonthsByEnd_30c() { DateTime d = new DateTime(1959, 3, 30); Assert.AreEqual(d, d.AddMonthsByEnd(30, 0)); Assert.AreEqual(new DateTime(1959, 4, 30), d.AddMonthsByEnd(30, 1)); Assert.AreEqual(new DateTime(1959, 5, 30), d.AddMonthsByEnd(30, 2)); Assert.AreEqual(new DateTime(1960, 3, 1), d.AddMonthsByEnd(30, 11)); Assert.AreEqual(new DateTime(1960, 3, 30), d.AddMonthsByEnd(30, 12)); Assert.AreEqual(new DateTime(1960, 4, 30), d.AddMonthsByEnd(30, 13)); Assert.AreEqual(new DateTime(1960, 5, 30), d.AddMonthsByEnd(30, 14)); Assert.AreEqual(new DateTime(1960, 6, 30), d.AddMonthsByEnd(30, 15)); Assert.AreEqual(new DateTime(1959, 3, 2), d.AddMonthsByEnd(30, -1)); Assert.AreEqual(new DateTime(1959, 1, 30), d.AddMonthsByEnd(30, -2)); Assert.AreEqual(new DateTime(1958, 4, 30), d.AddMonthsByEnd(30, -11)); Assert.AreEqual(new DateTime(1958, 3, 30), d.AddMonthsByEnd(30, -12)); Assert.AreEqual(new DateTime(1958, 3, 2), d.AddMonthsByEnd(30, -13)); }
public void AddMonthsByEnd_2c() { DateTime d = new DateTime(1959, 3, 2); Assert.AreEqual(d, d.AddMonthsByEnd(2, 0)); Assert.AreEqual(new DateTime(1959, 4, 2), d.AddMonthsByEnd(2, 1)); Assert.AreEqual(new DateTime(1959, 5, 2), d.AddMonthsByEnd(2, 2)); Assert.AreEqual(new DateTime(1960, 3, 2), d.AddMonthsByEnd(2, 12)); Assert.AreEqual(new DateTime(1960, 4, 2), d.AddMonthsByEnd(2, 13)); Assert.AreEqual(new DateTime(1960, 5, 2), d.AddMonthsByEnd(2, 14)); Assert.AreEqual(new DateTime(1960, 6, 2), d.AddMonthsByEnd(2, 15)); Assert.AreEqual(new DateTime(1959, 2, 2), d.AddMonthsByEnd(2, -1)); Assert.AreEqual(new DateTime(1959, 1, 2), d.AddMonthsByEnd(2, -2)); Assert.AreEqual(new DateTime(1958, 4, 2), d.AddMonthsByEnd(2, -11)); Assert.AreEqual(new DateTime(1958, 3, 2), d.AddMonthsByEnd(2, -12)); Assert.AreEqual(new DateTime(1958, 2, 2), d.AddMonthsByEnd(2, -13)); }
public void AddMonthsByEnd_1b() { DateTime d = new DateTime(1960, 3, 1); Assert.AreEqual(d, d.AddMonthsByEnd(1, 0)); Assert.AreEqual(new DateTime(1960, 4, 1), d.AddMonthsByEnd(1, 1)); Assert.AreEqual(new DateTime(1960, 5, 1), d.AddMonthsByEnd(1, 2)); Assert.AreEqual(new DateTime(1961, 3, 1), d.AddMonthsByEnd(1, 12)); Assert.AreEqual(new DateTime(1961, 4, 1), d.AddMonthsByEnd(1, 13)); Assert.AreEqual(new DateTime(1961, 5, 1), d.AddMonthsByEnd(1, 14)); Assert.AreEqual(new DateTime(1961, 6, 1), d.AddMonthsByEnd(1, 15)); Assert.AreEqual(new DateTime(1960, 2, 1), d.AddMonthsByEnd(1, -1)); Assert.AreEqual(new DateTime(1960, 1, 1), d.AddMonthsByEnd(1, -2)); Assert.AreEqual(new DateTime(1959, 4, 1), d.AddMonthsByEnd(1, -11)); Assert.AreEqual(new DateTime(1959, 3, 1), d.AddMonthsByEnd(1, -12)); Assert.AreEqual(new DateTime(1959, 2, 1), d.AddMonthsByEnd(1, -13)); }
public void AddMonthsByEnd_0c() { DateTime d = new DateTime(1959, 2, 28); Assert.AreEqual(d, d.AddMonthsByEnd(0, 0)); Assert.AreEqual(new DateTime(1959, 3, 31), d.AddMonthsByEnd(0, 1)); Assert.AreEqual(new DateTime(1959, 4, 30), d.AddMonthsByEnd(0, 2)); Assert.AreEqual(new DateTime(1960, 2, 29), d.AddMonthsByEnd(0, 12)); Assert.AreEqual(new DateTime(1960, 3, 31), d.AddMonthsByEnd(0, 13)); Assert.AreEqual(new DateTime(1960, 4, 30), d.AddMonthsByEnd(0, 14)); Assert.AreEqual(new DateTime(1960, 5, 31), d.AddMonthsByEnd(0, 15)); Assert.AreEqual(new DateTime(1959, 1, 31), d.AddMonthsByEnd(0, -1)); Assert.AreEqual(new DateTime(1958, 12, 31), d.AddMonthsByEnd(0, -2)); Assert.AreEqual(new DateTime(1958, 3, 31), d.AddMonthsByEnd(0, -11)); Assert.AreEqual(new DateTime(1958, 2, 28), d.AddMonthsByEnd(0, -12)); Assert.AreEqual(new DateTime(1958, 1, 31), d.AddMonthsByEnd(0, -13)); }