Should I create a DateRange object?

Several of my domain objects contain date ranges as a pair of start and end date properties:

public class Period { public DateTime EffectiveDate { get; set; } public DateTime ThroughDate { get; set; } } public class Timeline { public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } } 

And I am with a lot of this:

 abstract public int Foo(DateTime startDate, DateTime endDate); abstract public decimal Bar(DateTime startDate, DateTime endDate); abstract public ICollection<C5.Rec<DateTime, DateTime>> FooBar(DateTime startDate, DateTime endDate); 

The latter made me wonder ... Should I implement the DateRange class? I do not know about this in BCL.

In my experience, the depth of the hierarchy of objects often complicates the situation. These objects are sent to the RDLC reports displayed by the ReportViewer control, but this is secondary. I will look towards the model, and not vice versa. However, we are not tied to property names and will agree to a compromise with something like:

 public class DateRange { public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } } Period p = new Period(); DateTime t = p.EffectiveDateRange.StartDate; 

The benefit of the DateRange class will be a centralized confirmation of the end date following the start date, and will simplify my method signatures:

 abstract public int Foo(DateRange dateRange); abstract public decimal Bar(DateRange dateRange); abstract public ICollection<DateRange> FooBar(DateRange dateRange); 

I'm just not sure that the DateRange class will not make me more worried than its value. Opinions?

Side question: Have I missed the generic generic class of a general-purpose tuple in BCL? I know that in different namespaces there are some very specific ones. The pollution of my public domain method signatures with C5 types is very, very dirty.

+44
tuples model date-range
Dec 04 '09 at 7:56
source share
5 answers

No, you did not miss a general class.

I have a Range type in MiscUtil that might interest you, and that certainly makes DateTime manipulations easier. Referring to Marc's answer, I can't remember if this is a structure or a class - you can, of course, change it.

This is nice and easy to step over due to generics shenanigans tokens (assuming you are using .NET 3.5, at least it is possible with 2.0, but not supported at the moment);

 Range<DateTime> range = 19.June(1976).To(DateTime.Today); foreach (DateTime date in range.Step(1.Days()) { // I was alive in this day } 

(It also uses a bunch of extension methods - more useful for a test than for production.)

To answer another question in Mark's answer, Noda Time will certainly be able to express the concept of a date more suitable than .NET. API, but at the moment we don’t have anything like a range ... This is a good idea, though - I added a function request .

+33
Dec 04 '09 at 8:03
source share

If you work a lot with dates, yes - the range can be convenient. This is actually one of those rare cases where you probably should write it as a struct (immutable). Please note, however, that β€œNoda Time” is likely to give you all this and more (when it is completed). I used to plan software; I had several such structures (for slightly different tasks).

Please note: there is no convenient BCL design for this.

Also - think of all the great methods (and possibly operators) that you can centralize when you have a range; "contains" ("datetime" of another range, including / excluding limits?), "crosses", offsets (time interval), etc. A certain case of having a type to handle it. Note that at the ORM level it is easier if your ORM supports composite values ​​- I believe that NHibernate does and, possibly, EF 4.0.

+5
Dec 04 '09 at 7:59
source share

In .NET 4.0 or later, the Tuple <> type was added to handle multiple values.

With a tuple type, you can define your own combination of values ​​on the fly. Your problem is very common and similar to when a function wants to return multiple values. Previously, you had to use variables or create a new class just for a function response.

 Tuple<DateTime, DateTime> dateRange = new Tuple<DateTime, DateTime>(DateTime.Today, DateTime.Now); 

Whichever route you choose, I think you are definitely following the right approach. You give real meaning to the fact that the two pairs are the same. This is self-documenting code and, most importantly, right in the code structure.

+5
May 28 '15 at 22:21
source share

I do not know of any native .NET class such as DateRange. The closest is probably a combination of DateTime + TimeSpan or DateTime / DateTime.

I think you want pretty cool.

0
Dec 04 '09 at 8:01
source share

As Mark and John have already mentioned, I would create this as a type of value that is immutable. I would decide to implement it as a structure and implement the IEquatable and IComparable interfaces.

When using ORM, such as NHibernate, you can save the type of the value inside the table that represents the entity.

0
Dec 04 '09 at 8:12
source share



All Articles