Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Small method to calculate since time
Message
From
09/10/2011 09:07:38
 
 
General information
Forum:
ASP.NET
Category:
Coding, syntax and commands
Environment versions
Environment:
VB 9.0
OS:
Windows 7
Network:
Windows 2003 Server
Database:
MS SQL Server
Application:
Web
Miscellaneous
Thread ID:
01525501
Message ID:
01525907
Views:
43
Modified the code a bit. It's the same but different

Added range checking on the fields of the structure - useful for developing
Added a couple of constructors - including one that accepts two DateTimes
Since I had to test it - I have added IEquatable< DateTimeSpan >, IComparable and IComparable< DateTimeSpan >

Following
- The class
- Extension Method Between()
- Constants ( used size of Int32)
- test program

The class
	public struct DateTimeSpan
		:	IEquatable<DateTimeSpan>, 
			IComparable, IComparable<DateTimeSpan>
	{
		#region Fields
		//______________________________________________________________________
		private Int32 _Years;
		public Int32 Years
		{
			get { return _Years; }
			set 
			{
				if (!value.Between(0, 9999))
					throw new ArgumentOutOfRangeException("Years", "between 0 and 9999");
				_Years = value ;
			}
		}
		//______________________________________________________________________
		private byte _Months;
		public Int32 Months
		{
			get { return _Months; }
			set
			{
				if (!value.Between(0, 11))
					throw new ArgumentOutOfRangeException("Months", "between 0 and 11");
				_Months = unchecked((byte)value);
			}
		}
		//______________________________________________________________________
		private byte _Days;
		public Int32 Days
		{
			get { return _Days; }
			set
			{
				if (!value.Between(0, 30))
					throw new ArgumentOutOfRangeException("Days", "between 0 and 30");
				_Days = unchecked((byte)value);
			}
		}
		//______________________________________________________________________
		private byte _Hours;
		public Int32 Hours
		{
			get { return _Hours; }
			set
			{
				if (!value.Between(0, 23))
					throw new ArgumentOutOfRangeException("Hours", "between 0 and 23");
				_Hours = unchecked((byte)value);
			}
		}
		//______________________________________________________________________
		private byte _Minutes;
		public Int32 Minutes
		{
			get { return _Minutes; }
			set
			{
				if (!value.Between(0, 59))
					throw new ArgumentOutOfRangeException("Hours", "between 0 and 59");
				_Minutes = unchecked((byte)value);
			}
		}
		//______________________________________________________________________
		private byte _Seconds;
		public Int32 Seconds
		{
			get { return _Seconds; }
			set
			{
				if (!value.Between(0, 59))
					throw new ArgumentOutOfRangeException("Seconds", "between 0 and 59");
				_Seconds = unchecked((byte)value);
			}
		}
		//______________________________________________________________________
		private ushort _MilliSeconds;
		public Int32 MilliSeconds
		{
			get { return _MilliSeconds; }
			set
			{
				if (!value.Between(0, 999))
					throw new ArgumentOutOfRangeException("MilliSeconds", "between 0 and 999");
				_MilliSeconds = unchecked((ushort)value);
			}
		}
		//______________________________________________________________________
		//______________________________________________________________________
		#endregion Fields
		#region Constructors
		//______________________________________________________________________
		public DateTimeSpan(int years, int months, int days)
			: this(years, months, days, 0,0,0, 0)
		{
		}
		//______________________________________________________________________
		public DateTimeSpan(
			int years, int months, int days,
			int hours, int minutes, int seconds
			) : this(years, months, days, hours, minutes, seconds, 0)
		{

		}
		//______________________________________________________________________
		public DateTimeSpan(
			int years, int months, int days, 
			int hours, int minutes, int seconds, int milliSeconds
			)
		{
			HashCode = _Years = _MilliSeconds = _Months = _Days = _Hours = _Minutes = _Seconds = 0;
			HasCodePresent = false;

			Years = years; Months = months; Days = days;
			Hours = hours; Minutes = minutes; Seconds = seconds;
			MilliSeconds = milliSeconds;

			
		}
		//______________________________________________________________________
		/*
		 * start:	2012/03/14
		 * end:		2022/04/15
		 * years: 2022 - 2012, 
		 * months: 04-03
		 * days 2022/04/14 >> 2022/04/15 = 1
		 * 
		 * start:	2012/03/14
		 * end:		2022/02/13
		 * years:	2022 - 2012 + 1
		 * months: 02 - 03 + 12
		 * days:	2022/01/14 >> 2022/02/13 = 30
		 */

		public DateTimeSpan(DateTime start, DateTime end)
		{
			if (start > end)
				throw new ArgumentException("startDate <= endDate");

			HashCode = _Years = _MilliSeconds = _Months = _Days = _Hours = _Minutes = _Seconds = 0;

			HasCodePresent = false;

			Years = end.Year - start.Year;

			int months = end.Month - start.Month;

			if (months < 0)
			{
				months += 12;
				Years--;
			}

			TimeSpan tsStart = new TimeSpan(start.Day, start.Hour, start.Minute, start.Second, start.Millisecond);
			TimeSpan tsEnd = new TimeSpan(end.Day, end.Hour, end.Minute, end.Second, end.Millisecond);

			if (tsStart > tsEnd)
			{
				if (--months < 0)
				{
					months += 12;
					Years--;		
				}
			
			}
			Months = months;

			DateTime between = start.AddYears(Years).AddMonths(months);
			TimeSpan delta = end - between;
			

			Days = delta.Days;
			Hours = delta.Hours;
			Minutes = delta.Minutes;
			Seconds = delta.Seconds;
			MilliSeconds = delta.Milliseconds;
			
		}
		//______________________________________________________________________
		#endregion Constructors
		//______________________________________________________________________
		#region ToString
		//______________________________________________________________________
		public override string ToString()
		{
			return string.Format("Years:{0} Months:{1} Days:{2} Hours:{3} Minutes:{4} Seconds:{5}",
				Years, Months, Days, Hours, Minutes, Seconds);
		}
		//______________________________________________________________________
		public string ToString(bool comparable)
		{
			if (!comparable)
				return ToString();

			return String.Format("{0:0000}{1:00}{2:00}{3:00}{4:00}{5:00}{6:000}", 
					Years,Months, Days, 
					Hours, Minutes, Seconds, MilliSeconds);
		}
		//______________________________________________________________________
		#endregion ToString

		#region IComparable
		//______________________________________________________________________
		public int CompareTo(object other)
		{
			if (other == null)
				return 1;

			if (!(other is DateTimeSpan))
				throw new ArgumentException("not a DateTimeSpan", "other");

			return CompareTo((DateTimeSpan)other);

		}
		//______________________________________________________________________
		#endregion IComparable

		#region IComparable<T>
		//______________________________________________________________________
		public int CompareTo(DateTimeSpan other)
		{
			return String.CompareOrdinal(ToString(true), other.ToString(true));
		}
		//______________________________________________________________________
		#endregion IComparable<T>

		#region Equals
		//______________________________________________________________________
		public override bool Equals(object other)
		{
			return other is DateTimeSpan ? Equals((DateTimeSpan)other) : false;
		}
		//______________________________________________________________________
		#endregion Equals
		#region IEquatable<T>
		//______________________________________________________________________
		public bool Equals(DateTimeSpan other)
		{
			return CompareTo(other) == 0;
		}
		//______________________________________________________________________
		#endregion IEquatable<T>

		#region GetHashCode
		//______________________________________________________________________
		private bool HasCodePresent;
		private int HashCode;

		public override int GetHashCode()
		{
			if (!HasCodePresent)
			{
				using (RandomNumberGenerator rnd = RandomNumberGenerator.Create())
				{
					byte[] bytes = new byte[ByteSize.Int32];
					rnd.GetBytes(bytes);
					HashCode = BitConverter.ToInt32(bytes, 0);

				}
			}
			return HashCode;
		}
		//______________________________________________________________________
		#endregion GetHashCode

		#region Operators
		//______________________________________________________________________
		public static bool operator ==(DateTimeSpan dts1, DateTimeSpan dts2)
		{
			return dts1.Equals(dts2);
		}
		//______________________________________________________________________
		public static bool operator !=(DateTimeSpan dts1, DateTimeSpan dts2)
		{
			return !(dts1 == dts2);
		}
		//______________________________________________________________________
		public static bool operator <(DateTimeSpan dts1, DateTimeSpan dts2)
		{
			return dts1.CompareTo(dts1) < 0;
		}
		//______________________________________________________________________
		public static bool operator >=(DateTimeSpan dts1, DateTimeSpan dts2)
		{
			return !(dts1 < dts2);
		}
		//______________________________________________________________________
		public static bool operator >(DateTimeSpan dts1, DateTimeSpan dts2)
		{
			return dts1.CompareTo(dts1) > 0;
		}
		//______________________________________________________________________
		public static bool operator <=(DateTimeSpan dts1, DateTimeSpan dts2)
		{
			return !(dts1 < dts2);
		}
		//______________________________________________________________________

		#endregion Operators
	}
Extension Method Between()
public static partial class ExtensionMethods_Comparison
	{
		//______________________________________________________________________
		/// <summary>
		/// tells whether s between s1 and s2
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="s"></param>
		/// <param name="s1"></param>
		/// <param name="s2"></param>
		/// <returns>true or false</returns>
		//
		// IComparable<T>
		//	- By definition, any object compares greater than a null reference 
		//	- two null references compare equal to each other
		public static bool Between<T>(this T s, T s1, T s2) where T : IComparable<T>
		{
			if (s != null)
				return (s.CompareTo(s1) >= 0) && (s.CompareTo(s2) <= 0);

			// s == null here

			/*
			 *		s1		s		s2		s1<=s	s<=s2	final
			 *		!=null	null	!null	false	true	false
			 *		null	null	!null	true	true	true	*
			 *		!null	null	null	false	true	false
			 *		null	null	null	true	true	true	*
			 */
			/*
			 * conclusion
			 * It does not matter whether s2 is null or not
			 *		s < non-null-s2
			 *		s == null-s2
			 *		hence always:	s <= s2
			 *		
			 * the only thing that matters is s1
			 *		non_null_s1 < s
			 *		null_s1 == s
			 */
			return (s1 == null);
		}
		//______________________________________________________________________
	}
Constants
	public class ByteSize
	{
		public const int Byte = 1;
		public const int SByte = 1;

		public const int Char = 2;

		public const int Int16 = 2;
		public const int UInt16 = 2;

		public const int Int32 = 4;
		public const int UInt32 = 4;

		public const int Int64 = 8;
		public const int UInt64 = 8;
	}
test program
	class Class1
	{
		static void Main(string[] args)
		{
			Test();
			Console.ReadLine();

		}

		static DateTimeSpanTest[] TestData = 
		{ new DateTimeSpanTest(
				new DateTime(2011, 04, 15, 0, 0, 0),
				new DateTime(2012, 03, 14, 0, 0, 0),
				new DateTimeSpan(0, 10, 28)
				)
			,new DateTimeSpanTest(
				new DateTime(2011, 04, 15, 17, 0, 0),
				new DateTime(2012, 04, 15, 16, 59, 59),
				new DateTimeSpan(0, 11, 30, 23, 59, 59)
				)
			,new DateTimeSpanTest(
				new DateTime(2011, 04, 15, 17, 0, 0),
				new DateTime(2013, 04, 15, 16, 59, 59),
				new DateTimeSpan(1, 11, 30, 23, 59, 59)
				)
			,new DateTimeSpanTest(
				new DateTime(2011, 04, 15, 17, 0, 0),
				new DateTime(2011, 04, 16, 16, 59, 59),
				new DateTimeSpan(0, 0, 0, 23, 59, 59)
				)
			,new DateTimeSpanTest(
				new DateTime(2012, 02, 28, 17, 0, 0),
				new DateTime(2012, 03, 01, 16, 59, 59),
				new DateTimeSpan(0, 0, 1, 23, 59, 59)
				)
			,new DateTimeSpanTest(
				new DateTime(2011, 02, 28, 17, 0, 0),
				new DateTime(2011, 03, 01, 16, 59, 59),
				new DateTimeSpan(0, 0, 0, 23, 59, 59)
				)
			,new DateTimeSpanTest(
				new DateTime(2011, 02, 28, 17, 0, 0),
				new DateTime(2011, 03, 01, 18, 01, 02),
				new DateTimeSpan(0, 0, 1, 01, 01, 02)
				)
		};
		static bool Test()
		{
			bool success = true;
			bool caseResult;

			foreach (DateTimeSpanTest testcase in TestData)
			{
				DateTimeSpan result = new DateTimeSpan(testcase.Start, testcase.End);
				caseResult = result == testcase.Delta;

				Console.WriteLine("{0} - {1} : \n{2} expected\n{3} got\n{4}",
						testcase.Start, testcase.End, testcase.Delta, result,
						 caseResult ? "OK" : "fail"
						);

				if (!caseResult)
				{
					success = false;
					break;
				}

			}
			return success;
		}
	}
	class DateTimeSpanTest
	{
		public DateTime Start;
		public DateTime End;
		public DateTimeSpan Delta;

		public DateTimeSpanTest(DateTime start, DateTime end, DateTimeSpan delta)
		{
			Start = start;
			End = end;
			Delta = delta;
		}
	}
Gregory
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform