Hey lovely programmers,
Today I had a big frustration with an XML file I had to parse containing 25 hours for the 30/10/2016.
All these hours where as String, and no way to use TimeSpan with 25 hours otherwise its the next day…
The best way I found is to generate a list with all the hours of the day but as DateTimeOffset to have the shift of hour at 2 AM for that particular day. And even better, every hour will contain an Index…
using System; using System.Collections.Generic; using System.Diagnostics; namespace Common.Helpers { [DebuggerDisplay("{StringRepresentation}")] public class DateTimeWrapper { public DateTime LocalTime { get; private set; } public DateTime UtcTime { get; private set; } public bool IsSecondOccurrence { get; set; } public int Index { get; private set; } public DateTimeWrapper(DateTime dateTime) { UtcTime = dateTime.ToUniversalTime(); LocalTime = dateTime.ToLocalTime(); IsSecondOccurrence = CheckIsSecondOccurrence(dateTime); CalculateIndex(); } private void CalculateIndex() { var utcStart = LocalTime.Date.ToUniversalTime(); var utc = UtcTime; var difference = utc - utcStart; Index = (int)difference.TotalMinutes / 60; } private bool CheckIsSecondOccurrence(DateTime dateTime) { var localStart = dateTime.ToLocalTime().Date; var localEnd = localStart.AddDays(1); var utc = localStart.ToUniversalTime(); var localTimes = new List<DateTime>(); while (utc.ToLocalTime() < localEnd) { if (dateTime.ToUniversalTime() == utc) { if (localTimes.Contains(utc.ToLocalTime())) { return true; } } localTimes.Add(utc.ToLocalTime()); utc = utc.AddMinutes(60); } return false; } public static List<DateTimeWrapper> GetHoursAvailableFor(DateTime day) { var localStart = day.ToLocalTime().Date; var localEnd = localStart.AddDays(1); var utc = localStart.ToUniversalTime(); var available = new List<DateTimeWrapper>(); while (utc.ToLocalTime() < localEnd) { available.Add(new DateTimeWrapper(utc)); utc = utc.AddMinutes(60); } return available; } public override int GetHashCode() { return UtcTime.GetHashCode(); } public override bool Equals(object obj) { if (obj == null) return false; return UtcTime.Equals(((DateTimeWrapper)obj).UtcTime); } public string StringRepresentation { get { return string.Format("{0:yyyyMMdd HH:mm}{1}", LocalTime, IsSecondOccurrence ? " *" : ""); } } public string StringRepresentationTimePartOnly { get { return string.Format("{0:HH:mm}{1}", LocalTime, IsSecondOccurrence ? " *" : ""); } } } }
If you need the Quarters instead of Hours, just replace the 60 by 15 at the two places…
Enjoy!