Reputation: 58
I want to handle Timeblocks, that means a set of two DateTimes which represent for example the presence of employees. Is there already any structure that i can use to search for a block before or after a specific time? There are many ways i can imagine to express the situation, like i said with two DateTimes for start and end or with a Datetime for start and a TimeSpan. But i want them to be handled in a kind of Collection. So is there anything similar that i can use or do i have to implement it completely on my own?
Thanks
Upvotes: 1
Views: 302
Reputation: 58
Thanks for the help! I will tae a closer look at the TimePeriod Library and do some experiments with Linq. I already have an approch that implements binary search, so if someones interested you can write me ;)
Upvotes: 0
Reputation: 3066
The class:
public class TimePeriod
{
public DateTime Oldest { get; set; }
public DateTime Newest { get; set; }
public TimePeriod(DateTime oldest, DateTime newest)
{
Oldest = oldest;
Newest = newest;
}
public bool Contains (DateTime time)
{
return Oldest.CompareTo(time) <= 0 && Newest.CompareTo(time) >= 0;
}
public bool IsAfter(DateTime time)
{
return Newest.CompareTo(time) <= 0;
}
public bool IsBefore(DateTime time)
{
return Oldest.CompareTo(time) >= 0;
}
}
The Test:
class Program
{
static void Main(string[] args)
{
var period = new TimePeriod(
DateTime.Now.AddDays(-2),
DateTime.Now.AddDays(1));
var date = DateTime.Now;
var contains = period.Contains(date); // true
var isBefore = period.IsBefore(date); // false
var isAfter = period.IsAfter(date); // false
date = DateTime.Now.AddDays(-10);
contains = period.Contains(date); // false
isBefore = period.IsBefore(date); // true
isAfter = period.IsAfter(date); // false
date = DateTime.Now.AddDays(10);
contains = period.Contains(date); // false
isBefore = period.IsBefore(date); // false
isAfter = period.IsAfter(date); // true
}
}
Now you can use collections and linq with extensions methods and lambda expression to look for time blocks.
Upvotes: 1
Reputation: 3538
I've used a DateSpan
structure before. You can extend is a much as one likes, but this will give you a starting point.
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace StackOverFlowDateSpan
{
[StructLayout(LayoutKind.Auto)]
[Serializable]
public struct DateSpan : IComparable, IComparable<DateSpan>, IEquatable<DateSpan>
{
public DateSpan(DateTime start, DateTime end)
: this()
{
Start = start;
End = end;
}
#region Properties
public TimeSpan Duration
{
get { return TimeSpan.FromTicks((End - Start).Ticks); }
}
public DateTime End { get; private set; }
public DateTime Start { get; private set; }
#endregion
public int CompareTo(DateSpan other)
{
long otherTicks = other.Duration.Ticks;
long internalTicks = Duration.Ticks;
return internalTicks > otherTicks ? 1 : (internalTicks < otherTicks ? -1 : 0);
}
public bool Equals(DateSpan other)
{
return End.Equals(other.End) && Start.Equals(other.Start);
}
public int CompareTo(object other)
{
if (other == null)
{
return 1;
}
if (!(other is DateSpan))
{
throw new ArgumentNullException("other");
}
return CompareTo((DateSpan)other);
}
public override bool Equals(object other)
{
if (ReferenceEquals(null, other))
{
return false;
}
return other is DateSpan && Equals((DateSpan)other);
}
public override int GetHashCode()
{
unchecked
{
return (End.GetHashCode() * 397) ^ Start.GetHashCode();
}
}
public static bool operator ==(DateSpan left, DateSpan right)
{
return left.Equals(right);
}
public static bool operator !=(DateSpan left, DateSpan right)
{
return !left.Equals(right);
}
private sealed class EndStartEqualityComparer : IEqualityComparer<DateSpan>
{
#region IEqualityComparer<DateSpan> Members
public bool Equals(DateSpan x, DateSpan y)
{
return x.End.Equals(y.End) && x.Start.Equals(y.Start);
}
public int GetHashCode(DateSpan obj)
{
unchecked
{
return (obj.End.GetHashCode() * 397) ^ obj.Start.GetHashCode();
}
}
#endregion
}
private static readonly IEqualityComparer<DateSpan> _endStartComparerInstance = new EndStartEqualityComparer();
public static IEqualityComparer<DateSpan> EndStartComparer
{
get { return _endStartComparerInstance; }
}
}
}
Upvotes: 0
Reputation: 5994
You may take a look at TimeSpan. Thats a struct to handle a "Timeblock"
Upvotes: 0
Reputation: 171178
This is not built-in. If you want to implement this yourself you probably want to create a struct. This will give you value-type copy semantics. Such a value behaves just like built-in types like int
or DateTime
. Very intuitive to use.
Upvotes: 0