172 lines
4.1 KiB
C#
172 lines
4.1 KiB
C#
using System;
|
|
|
|
namespace Unosquare.Swan {
|
|
/// <summary>
|
|
/// Represents a struct of DateTimeSpan to compare dates and get in
|
|
/// separate fields the amount of time between those dates.
|
|
///
|
|
/// Based on https://stackoverflow.com/a/9216404/1096693.
|
|
/// </summary>
|
|
public struct DateTimeSpan {
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="DateTimeSpan"/> struct.
|
|
/// </summary>
|
|
/// <param name="years">The years.</param>
|
|
/// <param name="months">The months.</param>
|
|
/// <param name="days">The days.</param>
|
|
/// <param name="hours">The hours.</param>
|
|
/// <param name="minutes">The minutes.</param>
|
|
/// <param name="seconds">The seconds.</param>
|
|
/// <param name="milliseconds">The milliseconds.</param>
|
|
public DateTimeSpan(Int32 years, Int32 months, Int32 days, Int32 hours, Int32 minutes, Int32 seconds, Int32 milliseconds) {
|
|
this.Years = years;
|
|
this.Months = months;
|
|
this.Days = days;
|
|
this.Hours = hours;
|
|
this.Minutes = minutes;
|
|
this.Seconds = seconds;
|
|
this.Milliseconds = milliseconds;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the years.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The years.
|
|
/// </value>
|
|
public Int32 Years {
|
|
get;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the months.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The months.
|
|
/// </value>
|
|
public Int32 Months {
|
|
get;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the days.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The days.
|
|
/// </value>
|
|
public Int32 Days {
|
|
get;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the hours.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The hours.
|
|
/// </value>
|
|
public Int32 Hours {
|
|
get;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the minutes.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The minutes.
|
|
/// </value>
|
|
public Int32 Minutes {
|
|
get;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the seconds.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The seconds.
|
|
/// </value>
|
|
public Int32 Seconds {
|
|
get;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the milliseconds.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The milliseconds.
|
|
/// </value>
|
|
public Int32 Milliseconds {
|
|
get;
|
|
}
|
|
|
|
internal static DateTimeSpan CompareDates(DateTime date1, DateTime date2) {
|
|
if(date2 < date1) {
|
|
DateTime sub = date1;
|
|
date1 = date2;
|
|
date2 = sub;
|
|
}
|
|
|
|
DateTime current = date1;
|
|
Int32 years = 0;
|
|
Int32 months = 0;
|
|
Int32 days = 0;
|
|
|
|
Phase phase = Phase.Years;
|
|
DateTimeSpan span = new DateTimeSpan();
|
|
Int32 officialDay = current.Day;
|
|
|
|
while(phase != Phase.Done) {
|
|
switch(phase) {
|
|
case Phase.Years:
|
|
if(current.AddYears(years + 1) > date2) {
|
|
phase = Phase.Months;
|
|
current = current.AddYears(years);
|
|
} else {
|
|
years++;
|
|
}
|
|
|
|
break;
|
|
case Phase.Months:
|
|
if(current.AddMonths(months + 1) > date2) {
|
|
phase = Phase.Days;
|
|
current = current.AddMonths(months);
|
|
if(current.Day < officialDay &&
|
|
officialDay <= DateTime.DaysInMonth(current.Year, current.Month)) {
|
|
current = current.AddDays(officialDay - current.Day);
|
|
}
|
|
} else {
|
|
months++;
|
|
}
|
|
|
|
break;
|
|
case Phase.Days:
|
|
if(current.AddDays(days + 1) > date2) {
|
|
current = current.AddDays(days);
|
|
TimeSpan timespan = date2 - current;
|
|
span = new DateTimeSpan(
|
|
years,
|
|
months,
|
|
days,
|
|
timespan.Hours,
|
|
timespan.Minutes,
|
|
timespan.Seconds,
|
|
timespan.Milliseconds);
|
|
phase = Phase.Done;
|
|
} else {
|
|
days++;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return span;
|
|
}
|
|
|
|
private enum Phase {
|
|
Years,
|
|
Months,
|
|
Days,
|
|
Done,
|
|
}
|
|
}
|
|
} |