问题 在DateTime中存储超过24小时


我在一个奇怪且非理性的行业工作,我们需要能够将时间表示为06:00:00到30:00:00而不是0:00:00到24:00:00。有没有办法使用DateTime类型?如果我尝试构造一个小于24的小时值的日期时间,则抛出异常。


4431
2018-04-01 20:53


起源

我很好奇。这是什么行业? - Chris Simpson
TARDIS制造商。 - JohnFx
@JohnFx - 毕竟是4月1日 - Chris Simpson
@JohnFx - 我猜: en.wikipedia.org/wiki/TARDIS ? - Nelson Rothermel
假设您有一个名为WeirdDateTime的DateTime。在WeirdDateTime类中,DateTime 2010-01-20 01:00:00对应的时间是否显示为2010-01-19 25:00:00? - Mark Byers


答案:


我认为这应该只是一个演示问题。

允许您的用户以这种奇怪的格式输入数据,并立即将其转换为UTC。对UTC时间进行所有计算。然后创建一个ToString方法将结果转换回您的奇怪格式。您可能还需要一些其他实用程序方法和属性,例如实现 WeirdDateTime.Day

您可以围绕DateTime编写一个包装类,并拥有该类所需的所有转换和实用程序方法。我已经开始了 - 通过以奇怪的格式从字符串中实现解析。这不是任何准备好的生产代码,但也许它可以为您提供一些如何处理此问题的想法:

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);
    }
}

10
2018-04-01 21:07





我怀疑你能做到你正在寻找的东西,但我希望你可以创建自己的DateTime类,只需在该值上增加+6小时。即内部存储00 - 24,但get / set方法使其看起来像06 - 30。


2
2018-04-01 20:57



是的,您可以从现有的日期时间类继承并覆盖涉及小时的方法/属性 - Chris Simpson
@Chris Simpson,你不能从现有的DateTime结构继承。 - šljaker
需要使用TimeSpan这样的东西。 - Gabe
@šljaker啊,我不知道。它只需要是一个包装类 - Chris Simpson


用一个怎么样? 时间跨度 相反?

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);  

然后使用 TotalHours TimeSpan obj的财产


2
2018-04-01 20:55



我确实尝试过使用TimeSpan,但是超过24小时的任何时间都会延续到当天。因此,例如36:00:00最终将作为TimeSpan的1:12:00:00结束。 - Rob
这怎么回事?只需使用yourTimeSpan.TotalHours即可。 - Taylor Leese
@Rob然后使用TimeSpan obj的TotalHours属性。 - Gabe


只需让您的业务逻辑存储/返回DateTime.Hours.Add(6)。您必须在显示逻辑中注意这一点。


0
2018-04-01 20:58





如何使用普通的DateTime存储实际时间,并编写一个存储(或派生自)DateTime的新类,并具有调整输出的ToString()。


0
2018-04-01 20:59





  1. 您应该使用TimeSpan,而不是DateTime。
  2. TimeSpan的格式选项是

    a:[天]。[小时]:[分钟]:[秒]。[小秒]

    b:[天]。[小时]:[分钟]:[秒]

    c:[天]。[小时]:[分钟]

    d:[天]。[小时]

    e:[天]

    f:[小时]:[分钟]:[秒]。[小秒]

    g:[小时]:[分钟]:[秒]

    h:[小时]:[分钟]


0
2018-04-01 21:03



谢谢,我完全同意:) - Gabe