PageRenderTime 66ms CodeModel.GetById 31ms app.highlight 16ms RepoModel.GetById 14ms app.codeStats 0ms

/Utilities/Helpers/DateHelper.cs

#
C# | 393 lines | 257 code | 25 blank | 111 comment | 33 complexity | ea05b37f10fc8fbb0bf7eeda3ca48c35 MD5 | raw file
  1using System;
  2using System.Globalization;
  3using NUnit.Framework;
  4
  5namespace Delta.Utilities.Helpers
  6{
  7	/// <summary>
  8	/// Date helper class, mostly used just to present date times in a common
  9	/// format (like ISO date strings), but also has some helper methods to
 10	/// check different dates and parse date strings.
 11	/// </summary>
 12	public static class DateHelper
 13	{
 14		#region GetTimeString (Static)
 15		/// <summary>
 16		/// GetTimeString
 17		/// </summary>
 18		/// <param name="time">Time</param>
 19		/// <returns>String</returns>
 20		public static string GetTimeString(this DateTime time)
 21		{
 22			return String.Format("{0:00}:{1:00}", time.Hour, time.Minute);
 23		}
 24		#endregion
 25
 26		#region GetForumDateAndTime (Static)
 27		/// <summary>
 28		/// Get forum date and time in german format, day.month.year hour:minute
 29		/// </summary>
 30		/// <param name="date">Date</param>
 31		/// <returns>String</returns>
 32		public static string GetForumDateAndTime(this DateTime date)
 33		{
 34			string dateString =
 35				String.Format("{0:00}.{1:00}.{2}", date.Day, date.Month, date.Year);
 36			string timeString =
 37				// Skip time if it is 00:00 (which usually means no time is given)
 38				(date.Hour != 0 || date.Minute != 0
 39				 	? String.Format("{0:00}:{1:00}", date.Hour, date.Minute)
 40				 	: "");
 41
 42			// Make bold if this was posted today!
 43			bool wasPostedToday =
 44				date.DayOfYear == DateTime.Now.DayOfYear &&
 45				date.Year == DateTime.Now.Year;
 46			if (wasPostedToday &&
 47			    String.IsNullOrEmpty(timeString) == false)
 48			{
 49				return String.Format("<b>{0}</b>", timeString);
 50			}
 51			else
 52			{
 53				return String.Format("{0} {1}", dateString, timeString);
 54			}
 55		}
 56		#endregion
 57
 58		#region GetAtForumDateAndTime (Static)
 59		/// <summary>
 60		/// Get at forum date and time
 61		/// </summary>
 62		/// <param name="date">DateHelper</param>
 63		/// <returns>String</returns>
 64		public static string GetAtForumDateAndTime(this DateTime date)
 65		{
 66			string dateString =
 67				String.Format("{0:00}.{1:00}.{2}", date.Day, date.Month, date.Year);
 68			string timeString =
 69				// Skip time if it is 00:00 (which usually means no time is given)
 70				(date.Hour != 0 || date.Minute != 0
 71				 	? String.Format("{0:00}:{1:00}", date.Hour, date.Minute)
 72				 	: "");
 73
 74			// Make bold if this was posted today!
 75			bool wasPostedToday =
 76				date.DayOfYear == DateTime.Now.DayOfYear &&
 77				date.Year == DateTime.Now.Year;
 78			if (wasPostedToday &&
 79			    String.IsNullOrEmpty(timeString) == false)
 80			{
 81				return String.Format("um <b>{0}</b>", timeString);
 82			}
 83			else
 84			{
 85				return String.Format("am {0} {1}", dateString, timeString);
 86			}
 87		}
 88		#endregion
 89
 90		#region GetDateFromString (Static)
 91		/// <summary>
 92		/// Get date from string
 93		/// </summary>
 94		/// <param name="dateString">Date string</param>
 95		/// <returns>Date time</returns>
 96		public static DateTime GetDateFromString(string dateString)
 97		{
 98			// First check if this contains a space and might be a date + time
 99			if (dateString.Contains(" "))
100			{
101				return GetDateAndTimeFromString(dateString);
102			}
103
104			// Try to get it the normal way ^^
105			DateTime ret = DateTime.Now;
106			bool dateSucceeded = true;
107			try
108			{
109				dateSucceeded = DateTime.TryParse(dateString,
110					CultureInfo.InvariantCulture, DateTimeStyles.None, out ret);
111			}
112			catch
113			{
114			}
115
116			if (dateSucceeded == false)
117			{
118				try
119				{
120					string[] dateParts = dateString.SplitAndTrim('.');
121					if (dateParts.Length >= 3)
122					{
123						ret = new DateTime(
124							Convert.ToInt32(dateParts[2]),
125							Convert.ToInt32(dateParts[1]),
126							Convert.ToInt32(dateParts[0]));
127					}
128					else if (dateParts.Length == 1)
129					{
130						// Support formats like "2011-07-27" as well (should already be
131						// handled above, but sometimes it does not work).
132						dateParts = dateString.SplitAndTrim('-');
133						if (dateParts.Length >= 3)
134						{
135							ret = new DateTime(
136								Convert.ToInt32(dateParts[0]),
137								Convert.ToInt32(dateParts[1]),
138								Convert.ToInt32(dateParts[2]));
139						}
140						else
141						{
142							// Finally check for American dates with / like "07/27/2011"
143							dateParts = dateString.SplitAndTrim('/');
144							if (dateParts.Length >= 3)
145							{
146								ret = new DateTime(
147									Convert.ToInt32(dateParts[2]),
148									Convert.ToInt32(dateParts[0]),
149									Convert.ToInt32(dateParts[1]));
150							}
151							else
152							{
153								// Just grab the year, but even that might not work ..
154								ret = new DateTime(
155									Convert.ToInt32(dateParts[0]), 1, 1);
156							}
157						}
158					}
159				}
160				catch { }
161				// catch
162
163				// If this did not work, then just use the current time.
164				// This sometimes seems to happen with WebNews, but not often!
165				if (ret.Year <= 1)
166				{
167					ret = DateTime.Now;
168				}
169			}
170
171			return ret;
172		}
173		#endregion
174
175		#region GetDateAndTimeFromString (Static)
176		/// <summary>
177		/// Get date and time from string
178		/// </summary>
179		/// <param name="dateString">Date string</param>
180		/// <returns>Date time</returns>
181		public static DateTime GetDateAndTimeFromString(string dateString)
182		{
183			if (dateString.Trim().Length == 0)
184			{
185				return DateTime.Now;
186			}
187
188			DateTime date = DateTime.Now;
189			try
190			{
191				// You might ask yourself why go through all this trouble parsing
192				// the date ourselves when DateTime.TryParse can do the same. Well,
193				// this is several times faster and most dates are in this format :)
194				string[] dateAndTime = dateString.Split(new[]
195				{
196					' ', ':'
197				});
198				date = GetDateFromString(dateAndTime[0]);
199				if (dateAndTime.Length >= 3)
200				{
201					date = date.AddHours(Convert.ToInt32(dateAndTime[1]));
202					date = date.AddMinutes(Convert.ToInt32(dateAndTime[2]));
203					if (dateAndTime.Length >= 4)
204					{
205						date = date.AddSeconds(Convert.ToInt32(dateAndTime[3]));
206					}
207				}
208			}
209			catch
210			{
211				// Else just use the normal parser
212				DateTime.TryParse(dateString, out date);
213			}
214
215			return date;
216		}
217		#endregion
218
219		#region IsDateNewer (Static)
220		/// <summary>
221		/// Is date newer than the older date. Very useful for file comparisions.
222		/// </summary>
223		/// <param name="newerDate">Newer date</param>
224		/// <param name="olderDate">Older date</param>
225		/// <returns>True if the newer date is newer than the older date</returns>
226		public static bool IsDateNewer(DateTime newerDate, DateTime olderDate)
227		{
228			return newerDate.CompareTo(olderDate) == 1;
229		}
230		#endregion
231
232		#region IsDateInRange (Static)
233		/// <summary>
234		/// Is date in range. Will return true if currentData is between beginDate
235		/// and endDate.
236		/// </summary>
237		/// <param name="currentDate">Current date</param>
238		/// <param name="beginDate">Range begin</param>
239		/// <param name="endDate">Range end</param>
240		/// <returns>
241		/// True if currentData is between beginDate and endDate.
242		/// </returns>
243		public static bool IsDateInRange(this DateTime currentDate,
244			DateTime beginDate, DateTime endDate)
245		{
246			return
247				beginDate.CompareTo(currentDate) < 1 &&
248				endDate.CompareTo(currentDate) > -1;
249		}
250		#endregion
251
252		#region AreSameDays (Static)
253		/// <summary>
254		/// Are day1 and day2 are the same day?
255		/// </summary>
256		/// <param name="day1">Day 1</param>
257		/// <param name="day2">Day 2</param>
258		/// <returns>
259		/// True if the days are the same (ignoring all the other datetime values).
260		/// </returns>
261		public static bool AreSameDays(DateTime day1, DateTime day2)
262		{
263			return day1.Date.CompareTo(day2.Date) == 0;
264		}
265		#endregion
266
267		#region GetIsoDate (Static)
268		/// <summary>
269		/// Returns the "Iso Date" stamp (Year-Month-Day).
270		/// </summary>
271		/// <param name="date">Date</param>
272		/// <returns>"Iso Date" stamp (Year-Month-Day)</returns>
273		public static string GetIsoDate(this DateTime date)
274		{
275			return date.Year + "-" +
276			       date.Month.ToString("00") + "-" +
277			       date.Day.ToString("00");
278		}
279		#endregion
280
281		#region GetIsoTime (Static)
282		/// <summary>
283		/// Get Iso time stamp (Hour:Minute:Second)
284		/// </summary>
285		/// <param name="time">Datetime input</param>
286		/// <returns>String with the time in hours:minutes:seconds</returns>
287		public static string GetIsoTime(this DateTime time)
288		{
289			return time.Hour.ToString("00") + ":" +
290			       time.Minute.ToString("00") + ":" +
291			       time.Second.ToString("00");
292		}
293		#endregion
294
295		#region GetIsoTimeWithMiliseconds (Static)
296		/// <summary>
297		/// Get iso time with miliseconds. Note: DateTime is not very accurate,
298		/// use better timings with the Time or GameTime classes for ingame
299		/// purposes (profiling, debugging, etc. otherwise strings should not be
300		/// needed anyway). This is mostly 
301		/// </summary>
302		/// <param name="time">Time for output</param>
303		/// <returns>
304		/// Text with the time in hours:minutes:seconds.milliseconds format.
305		/// </returns>
306		public static string GetIsoTimeWithMiliseconds(this DateTime time)
307		{
308			return time.Hour.ToString("00") + ":" +
309			       time.Minute.ToString("00") + ":" +
310			       time.Second.ToString("00") + "." +
311			       time.Millisecond.ToString("000");
312		}
313		#endregion
314
315		#region GetIsoDateTime (Static)
316		/// <summary>
317		/// Get Iso date time stamp (Year-Month-Day Hour:Minute:Second)
318		/// </summary>
319		/// <param name="dateTime">Date Time</param>
320		/// <returns>Date Time</returns>
321		public static string GetIsoDateTime(this DateTime dateTime)
322		{
323			return GetIsoDate(dateTime) + " " + GetIsoTime(dateTime);
324		}
325		#endregion
326
327		#region IsDate (Static)
328		/// <summary>
329		/// Is date, to check if for example the string contains DateTime value
330		/// if not return false
331		/// </summary>
332		/// <param name="obj">Object to check if this is a date</param>
333		/// <returns>True if this is a date, false otherwise</returns>
334		public static bool IsDate(Object obj)
335		{
336			string dateString = obj.ToString();
337			try
338			{
339				DateTime dateLocal = DateTime.Parse(dateString);
340				if (dateLocal != DateTime.MinValue &&
341				    dateLocal != DateTime.MaxValue)
342				{
343					return true;
344				}
345				return false;
346			}
347			catch
348			{
349				return false;
350			}
351		}
352		#endregion
353
354		/// <summary>
355		/// Test
356		/// </summary>
357		internal class DateHelperTests
358		{
359			#region IsDateNewer
360			/// <summary>
361			/// Is date newer
362			/// </summary>
363			[Test]
364			public void IsDateNewer()
365			{
366				DateTime newerDate = new DateTime(2007, 6, 21);
367				DateTime olderDate = new DateTime(2007, 6, 20);
368
369				Assert.True(DateHelper.IsDateNewer(newerDate, olderDate));
370				Assert.False(DateHelper.IsDateNewer(newerDate, newerDate));
371
372				DateTime notOlderDate = new DateTime(2008, 6, 21);
373				Assert.False(DateHelper.IsDateNewer(newerDate, notOlderDate));
374			}
375			#endregion
376
377			#region GetIsoDateTime
378			/// <summary>
379			/// Get iso date time stamp
380			/// </summary>
381			[Test]
382			public void GetIsoDateTime()
383			{
384				Assert.Equal("2009-11-17 13:06:01",
385					new DateTime(2009, 11, 17, 13, 6, 1).GetIsoDateTime());
386				DateTime testTime = new DateTime(2009, 11, 17, 13, 6, 1);
387				Assert.Equal(testTime, GetDateAndTimeFromString(
388					testTime.GetIsoDateTime()));
389			}
390			#endregion
391		}
392	}
393}