tags:

views:

277

answers:

6

I work in a bizarre and irrational industry where we need to be able to represent the time of day as 06:00:00 to 30:00:00 instead of 0:00:00 to 24:00:00. Is there any way to do this using the DateTime type? If I try to construct a date time with an hour value greater than 24 it throws an exception.

+2  A: 

How about use a TimeSpan instead ?

DateTime departure = new DateTime(2010, 6, 12, 18, 32, 0);
DateTime arrival = new DateTime(2010, 6, 13, 22, 47, 0);
TimeSpan travelTime = arrival - departure;  
Console.WriteLine("{0} - {1} = {2}", arrival, departure, travelTime);  

Then use the TotalHours property of the TimeSpan obj

gmcalab
I did try using TimeSpan, however any hours over 24 will be rolled over into the day. So for example 36:00:00 would end up being 1:12:00:00 as a TimeSpan.
Rob
How is this a problem? Just use yourTimeSpan.TotalHours.
Taylor Leese
@Rob use the TotalHours property of the TimeSpan obj then.
gmcalab
+2  A: 

I doubt you can do exactly what you're looking for, but I expect that you could make your own DateTime class that simply adds +6 hrs to the value. i.e. stores 00 - 24 internally, but the get/set methods make it seem like 06 - 30.

Chris Thornton
Yes you can inherit from the existing date time class and override the methods/properties that involve the hour
Chris Simpson
@Chris Simpson, you can't inherit from the existing DateTime struct.
šljaker
Need to use TimeSpan for something like this.
gmcalab
@šljaker ah, I didn't know that. it would just have to be a wrapper class then
Chris Simpson
A: 

Just have your business logic store/return DateTime.Hours.Add(6). You'll have to be aware of this in your display logic.

Ian Jacobs
A: 

how 'bout using a normal DateTime to store the actual time, and writing a new class which stores (or derives from ) a DateTime, and has a ToString() which adjusts the output.

James Curran
A: 
  1. You should be using TimeSpan, not DateTime.
  2. The format options for TimeSpan is

    a: [days].[hours]:[minutes]:[seconds].[fractional seconds]

    b: [days].[hours]:[minutes]:[seconds]

    c: [days].[hours]:[minutes]

    d: [days].[hours]

    e: [days]

    f: [hours]:[minutes]:[seconds].[fractional seconds]

    g: [hours]:[minutes]:[seconds]

    h: [hours]:[minutes]

Jonathan Allen
Thanks, I totally agree :)
gmcalab
+10  A: 

I think this should be a presentation issue only.

Allow your users to input data in this weird format, and immediately convert it to UTC. Do all calculations on the UTC times. Then create a ToString method to convert the results back into your weird format. You will probably also need some other utility methods and properties such as an implementation of WeirdDateTime.Day.

You could write a wrapper class around a DateTime and have all the conversion and utility methods you need on that class. I've had a go at starting it - by implementing parsing from a string in weird format. This isn't production code ready by any means, but perhaps it can give you a few ideas of how you could approach this:

class WeirdDateTime
{
    public DateTime DateTime { get; set; }

    public WeirdDateTime(int year, int month, int day, int hour, int minute, int second, DateTimeKind kind)
    {
        if (hour < 6 || hour >= 30)
            throw new ArgumentException("Not a valid WeirdDateTime", "hour");

        bool addDay;
        if (hour >= 24)
        {
            addDay = true;
            hour -= 24;
        }
        else
        {
            addDay = false;
        }

        DateTime dateTime = new DateTime(year, month, day, hour, minute, second, kind);
        if (addDay)
            dateTime = dateTime.AddDays(1);

        DateTime = dateTime;
    }

    public static WeirdDateTime Parse(string s)
    {
        Regex regex = new Regex(@"(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})");
        Match match = regex.Match(s);
        if (!match.Success)
            throw new FormatException("Not a valid WeirdDateTime");

        int[] parts = match.Groups.Cast<Group>()
            .Skip(1)
            .Select(x => int.Parse(x.Value))
            .ToArray();

        int year = parts[0];
        int month = parts[1];
        int day = parts[2];
        int hour = parts[3];
        int minute = parts[4];
        int second = parts[5];

        return new WeirdDateTime(year, month, day, hour, minute, second, DateTimeKind.Unspecified);
    }

    public override string ToString()
    {
        throw new NotImplementedException("Write this!");
    }
}

class Program
{
    public static void Main()
    {
        WeirdDateTime weirdDateTime = WeirdDateTime.Parse("2010-01-19 27:00:00");
        DateTime dateTimeUtc = weirdDateTime.DateTime.ToUniversalTime();
        Console.WriteLine(dateTimeUtc);
    }
}
Mark Byers