Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I represent a time only value in .NET?

You can use timespan

TimeSpan timeSpan = new TimeSpan(2, 14, 18);
Console.WriteLine(timeSpan.ToString());     // Displays "02:14:18".

[Edit]
Considering the other answers and the edit to the question, I would still use TimeSpan. No point in creating a new structure where an existing one from the framework suffice.
On these lines you would end up duplicating many native data types.


As others have said, you can use a DateTime and ignore the date, or use a TimeSpan. Personally I'm not keen on either of these solutions, as neither type really reflects the concept you're trying to represent - I regard the date/time types in .NET as somewhat on the sparse side which is one of the reasons I started Noda Time. In Noda Time, you can use the LocalTime type to represent a time of day.

One thing to consider: the time of day is not necessarily the length of time since midnight on the same day...

(As another aside, if you're also wanting to represent a closing time of a shop, you may find that you want to represent 24:00, i.e. the time at the end of the day. Most date/time APIs - including Noda Time - don't allow that to be represented as a time-of-day value.)


If that empty Date really bugs you, you can also to create a simpler Time structure:

// more work is required to make this even close to production ready
class Time
{
    // TODO: don't forget to add validation
    public int Hours   { get; set; }
    public int Minutes { get; set; }
    public int Seconds { get; set; }

    public override string ToString()
    {  
        return String.Format(
            "{0:00}:{1:00}:{2:00}",
            this.Hours, this.Minutes, this.Seconds);
    }
}

Or, why to bother: if you don't need to do any calculation with that information, just store it as String.


I say use a DateTime. If you don't need the date portion, just ignore it. If you need to display just the time to the user, output it formatted to the user like this:

DateTime.Now.ToString("t");  // outputs 10:00 PM

It seems like all the extra work of making a new class or even using a TimeSpan is unnecessary.


I think Rubens' class is a good idea so thought to make an immutable sample of his Time class with basic validation.

class Time
{
    public int Hours   { get; private set; }
    public int Minutes { get; private set; }
    public int Seconds { get; private set; }

    public Time(uint h, uint m, uint s)
    {
        if(h > 23 || m > 59 || s > 59)
        {
            throw new ArgumentException("Invalid time specified");
        }
        Hours = (int)h; Minutes = (int)m; Seconds = (int)s;
    }

    public Time(DateTime dt)
    {
        Hours = dt.Hour;
        Minutes = dt.Minute;
        Seconds = dt.Second;
    }

    public override string ToString()
    {  
        return String.Format(
            "{0:00}:{1:00}:{2:00}",
            this.Hours, this.Minutes, this.Seconds);
    }
}

In addition to Chibueze Opata:

class Time
{
    public int Hours   { get; private set; }
    public int Minutes { get; private set; }
    public int Seconds { get; private set; }

    public Time(uint h, uint m, uint s)
    {
        if(h > 23 || m > 59 || s > 59)
        {
            throw new ArgumentException("Invalid time specified");
        }
        Hours = (int)h; Minutes = (int)m; Seconds = (int)s;
    }

    public Time(DateTime dt)
    {
        Hours = dt.Hour;
        Minutes = dt.Minute;
        Seconds = dt.Second;
    }

    public override string ToString()
    {  
        return String.Format(
            "{0:00}:{1:00}:{2:00}",
            this.Hours, this.Minutes, this.Seconds);
    }

    public void AddHours(uint h)
    {
        this.Hours += (int)h;
    }

    public void AddMinutes(uint m)
    {
        this.Minutes += (int)m;
        while(this.Minutes > 59)
            this.Minutes -= 60;
            this.AddHours(1);
    }

    public void AddSeconds(uint s)
    {
        this.Seconds += (int)s;
        while(this.Seconds > 59)
            this.Seconds -= 60;
            this.AddMinutes(1);
    }
}