Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

A few 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 find myself 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 last one made me wonder ... Should I implement a DateRange class? I'm not aware of one in the BCL.

In my experience, making the object hierarchy deeper often complicates things. These objects do get sent to RDLC reports displayed by the ReportViewer control, but that's secondary. I'll bend the view to the model rather than vice versa. We aren't tied to the property names, though, and would be willing to 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;

A benefit of a DateRange class would be centralized validation of the end date coming after the start date, and it 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 a DateRange class won't get me into more trouble than its worth. Opinions?

Side question: Did I miss a generic general-purpose tuple class in the BCL somewhere? I know there's some very specific ones floating around in various namespaces. Polluting my public domain method signatures with C5 types feels very, very dirty.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
353 views
Welcome To Ask or Share your Answers For Others

1 Answer

No, you didn't miss a general purpose class.

I have a Range type in MiscUtil which you may be interested in - and it certainly makes for simple DateTime manipulation. Referring to Marc's answer, I can't remember whether this is a struct or a class - you'd be welcome to change it of course.

It's nice and easy to step through, due to Marc's generics shenanigans (assuming you're using .NET 3.5, at least - it's feasible 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
}

(That's also using a bunch of extension methods - more useful for test than production.)

To address the other point in Marc's answer, Noda Time will certainly be able to express the concept of a date more appropriately than the .NET API, but we don't have anything like a range at the moment... It's a nice idea though - I've added a feature request.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...