BBorg
BBorg

Reputation: 354

Just Date or Time

I'm just wondering ..

I have and object like this

public class Entry{

public DateTime? Date { get; set;} // This is just Date

public DateTime? StartTime { get; set; } //This is just Time

public TimeSpan Duration { get; set; } //Time spent on entry

}

Is there a more appropriate type than DateTime or better strategy to handling just Time and Date? Without the pain of having to add a DateTime.MinDate() to all my Start and End Times?

--- update ---

1 - I like to be able to request if Date or StartTime is Null seperartly on the Entry object.

2 - Entry should allow the user to input Duration without indication of date. Even a default date like DateTime.MinDate() seems like a poor design. (This is why i choose TimeSpan not Start and EndTime)

Upvotes: 3

Views: 749

Answers (4)

Guffa
Guffa

Reputation: 700720

Don't split up the date and time components where you store the data. You can provide properties to extract those if you like:

public class Entry {

   public DateTime StartPoint { get; set; }
   public TimeSpan Duration { get; set; }

   public DateTime StartDate { get { return StartPoint.Date; } }
   public TimeSpan StartTime { get { return StartPoint.TimeOfDay; } }
   public DateTime EndPoint { get { return StartPoint + Duration; } }
   public DateTime EndDate { get { return EndPoint.Date; } }
   public TimeSpan EndTime { get { return EndPoint.TimeOfDay; } }

}

Update:
If you want to have null values for date and time, you can add properties for that without having to split the date and time:

public class Entry{

   private DateTime _startPoint;

   public bool HasStartDate { get; private set; }
   public bool HasStartTime { get; private set; }
   public TimeSpan Duration { get; private set; }

   private void EnsureStartDate() {
      if (!HasStartDate) throw new ApplicationException("Start date is null.");
   }

   private void EnsureStartTime() {
      if (!HasStartTime) throw new ApplicationException("Start time is null.");
   }

   public DateTime StartPoint { get {
      EnsureStartDate();
      EnsureStartTime();
      return _startPoint;
   } }

   public DateTime StartDate { get {
      EnsureStartDate();
      return _startPoint.Date;
   } }

   public TimeSpan StartTime { get {
      EnsureStartTime();
      return _startPoint.TimeOfDay;
   } }

   public DateTime EndPoint { get { return StartPoint + Duration; } }

   public DateTime EndDate { get { return EndPoint.Date; } }

   public TimeSpan EndTime { get { return EndPoint.TimeOfDay; } }

   public Entry(DateTime startPoint, TimeSpan duration)
     : this (startPoint, true, true, duration) {}

   public Entry(TimeSpan duration)
     : this(DateTime.MinValue, false, false, duration) {}

   public Entry(DateTime startPoint, bool hasStartDate, bool hasStartTime, TimeSpan duration) {
      _startPoint = startPoint;
      HasStartDate = hasStartDate;
      HasStartTime = hasStartTime;
      Duration = duration;
   }

}

Upvotes: 6

Jim G.
Jim G.

Reputation: 15382

I'd like to compliment Guffa's answer with two more best practices:

  1. Store all of your dates as UTC in the database.
  2. Avoid System.DateTime and favor System.DateTimeOffset.
    1. SQL Server 2008’s datetimeoffset type is the equivalent of DateTimeOffset.

Upvotes: 0

LukeH
LukeH

Reputation: 269608

You could use a TimeSpan for your StartTime and EndTime properties. That's what the DateTime.TimeOfDay property returns.

There's also the DateTime.Date property which returns a DateTime with the time element set to midnight.

Having said that, I would probably recommend ditching your Date property altogether and storing full DateTimes (ie, date and time) in your StartTime and EndTime properties.

Upvotes: 6

Adam Robinson
Adam Robinson

Reputation: 185693

You're far better off leaving your references as DateTimes. If you only store the time, then you have issues when your Entry spans more than a 24-hour period. Store them as DateTimes as you have them now, and apply whatever formatting is necessary to represent just the time portion to your end-user.

Upvotes: 1

Related Questions