C# Datetime/Timespan按小时排序

C# Datetime/Timespan按小时排序,c#,C#,我有一个物品清单。每个对象都有一个DateTime属性 当我添加对象时,DateTime是通过ParseExact实例化的 public class Event { public Event(string time) { Time = DateTime.ParseExact(time, "HH:mm zzz", CultureInfo.InvariantCulture); } public DateTime Time { get; set; }

我有一个物品清单。每个对象都有一个
DateTime
属性

当我添加对象时,DateTime是通过ParseExact实例化的

public class Event
{
    public Event(string time)
    {
         Time = DateTime.ParseExact(time, "HH:mm zzz", CultureInfo.InvariantCulture);
    }

    public DateTime Time { get; set; }
}
这允许我添加如下项目:

Events.AddRange(new List<Event> { new Event("07:00 +" + timeZone), new Event("11:30 +" + timeZone), new Event("16:00 +" +timeZone), new Event("19:00 +" + timeZone), new Event("00:00 +" + timeZone), new Event("03:00 +" +timeZone) });
问题是,今天都是同一天

用上面的列表来说明(鉴于日期和时间是25/7 22:19,它将是:

[“22:22 25/7”,“23:59 25/7”,“5:12 25/7”,“7:30 25/7”,“15:55 25/7”]

我希望这能说明我的观点,因为日期应该是26号,过了午夜,等等

另一件事是,它返回的列表长度与输入长度一样长,但理想情况下,这种情况可以永远持续下去(希望这是有意义的)。如果能够请求10个项目,它将返回当前时间的下10个项目,这将非常好

编辑:澄清
我得到了一个DateTime列表,只有DateTime对象的小时和分钟是相关的。 从现在开始,我想获得下一个10、25或50个DateTimes对象。这可以生成,因为小时和分钟是datetime对象中唯一相关的数据。然后,这些项目应该现在就开始排序,以此类推

编辑2:时区 在上述代码中,时区=“0000”,UTC。
这将在用户端自动将时间转换为用户当前位置。

如果日期早于开始日期,则可以在日期中添加1天:

Events.Sort((x, y) =>
{
    var xTime = x.Time;
    var yTime = y.Time;
    if (xTime < startTime)
        xTime = xTime.AddDays(1);
    if (yTime < startTime)
        yTime = yTime.AddDays(1);

    return xTime.CompareTo(yTime);
});
排序后:

25/07/2015 22:22:00 
25/07/2015 23:59:00 
25/07/2015 05:12:00 
25/07/2015 07:30:00 
25/07/2015 15:55:00 

在@JonSkeet之后,我切换到一个TimeSpan对象,而不是DateTime

public List<Event> Events = new List<Event>();

public void InitializeTimers()
{
    Boss tequalt = new Boss("Tequatl the Sunless", BossPriority.HardCore) { Location = "Splintered Coast", Image = "tequatl.jpg" };
    Events.AddRange(new List<Event>
    {
        new Event("07:00", tequalt),
        new Event("11:30", tequalt)
    });
}

public List<Event> GetEvents(int count)
{
    InitializeTimers();
    var timeSpanPattern = Events.OrderBy(x => x.Time.Hours).ThenBy(x => x.Time.Hours);
    var newOrder = new List<Event>();
    var previousTimes = new List<Event>();
    foreach (var timespan in timeSpanPattern)
    {
        if (timespan.Time.CompareTo(DateTime.Now.TimeOfDay) != -1)
            newOrder.Add(timespan);
        else
            previousTimes.Add(timespan);
    }
    newOrder.AddRange(previousTimes);
    var finalList = new List<Event>();
    for (int i = 0; i < count; i++)
    {
        int extraDays = i / (newOrder.Count);
        int current = i - (extraDays * newOrder.Count);
        if (newOrder[current].Time.CompareTo(DateTime.Now.TimeOfDay) != 1)
            extraDays++;
        DateTime time = DateTime.ParseExact(newOrder[current].Time.Hours + ":" + newOrder[current].Time.Minutes + " +0000", "H:m zzz", CultureInfo.InvariantCulture).AddDays(extraDays);
        var newEvent = new Event { Boss = newOrder[current].Boss, DateAndTime = time, Time = newOrder[current].Time};
        newEvent.CalculateCountdown();
        finalList.Add(newEvent);
    }
    finalList.Sort((x,y) => x.DateAndTime.CompareTo(y.DateAndTime));
    return finalList;
}
它一点也不漂亮,但它完成了任务,并允许我指定需要多少项


如果有人知道如何优化上面的内容,我很乐意接受它作为答案。

你给出的代码不会编译-你的意思是
Time=DateTime.ParseExact(…);
?很抱歉,这正是我的意思:)很遗憾,你想做的其他事情我真的不清楚-你的意思是什么“由于日期应转到26日等”?您的意思是您正试图从现在开始创建下一个10
DateTime
值,其中包含列表中的时间?您所说的“时区”是什么意思“在这儿?我强烈怀疑它可能和我的不一样。如果你能更清楚地说明你真正想要实现的目标,我想可能有更好的方法来实现它。我认为这根本不是排序问题。我已经更新了我的问题,希望这更有意义。“我得到了一个DateTime列表,只有DateTime对象的小时和分钟是相关的。”在这种情况下,我建议您根本不要将它们存储为
DateTime
值。在.NET类型中,
TimeSpan
通常用于一天中的时间值-我个人不喜欢这样,但是
DateTime
也不理想。(我会使用我的野田佳彦时间库和
LocalTime
,但那是另一回事。)我会考虑实现这一点的最简单方法……虽然午夜后应该是26点,但在我这边似乎是这样工作的^^^谢谢你的努力!不幸的是,这没有给我继续生成事件的选项,如果这有意义的话:)@Jazerix,“午夜后应该是26”:显示的日期是事件中的日期,排序函数不会修改该日期。事件中的日期部分没有意义,因为您只想存储时间。但是,也许你应该在事件中存储完整的日期,这样可以使排序更容易。除了其他事情外,没有必要在中间进行所有的字符串解析。获取日期,然后将时间跨度添加到其中。。。
25/07/2015 22:22:00 
25/07/2015 23:59:00 
25/07/2015 05:12:00 
25/07/2015 07:30:00 
25/07/2015 15:55:00 
public List<Event> Events = new List<Event>();

public void InitializeTimers()
{
    Boss tequalt = new Boss("Tequatl the Sunless", BossPriority.HardCore) { Location = "Splintered Coast", Image = "tequatl.jpg" };
    Events.AddRange(new List<Event>
    {
        new Event("07:00", tequalt),
        new Event("11:30", tequalt)
    });
}

public List<Event> GetEvents(int count)
{
    InitializeTimers();
    var timeSpanPattern = Events.OrderBy(x => x.Time.Hours).ThenBy(x => x.Time.Hours);
    var newOrder = new List<Event>();
    var previousTimes = new List<Event>();
    foreach (var timespan in timeSpanPattern)
    {
        if (timespan.Time.CompareTo(DateTime.Now.TimeOfDay) != -1)
            newOrder.Add(timespan);
        else
            previousTimes.Add(timespan);
    }
    newOrder.AddRange(previousTimes);
    var finalList = new List<Event>();
    for (int i = 0; i < count; i++)
    {
        int extraDays = i / (newOrder.Count);
        int current = i - (extraDays * newOrder.Count);
        if (newOrder[current].Time.CompareTo(DateTime.Now.TimeOfDay) != 1)
            extraDays++;
        DateTime time = DateTime.ParseExact(newOrder[current].Time.Hours + ":" + newOrder[current].Time.Minutes + " +0000", "H:m zzz", CultureInfo.InvariantCulture).AddDays(extraDays);
        var newEvent = new Event { Boss = newOrder[current].Boss, DateAndTime = time, Time = newOrder[current].Time};
        newEvent.CalculateCountdown();
        finalList.Add(newEvent);
    }
    finalList.Sort((x,y) => x.DateAndTime.CompareTo(y.DateAndTime));
    return finalList;
}
[0] = Event.DateAndTime = "27-7-2015 11:30";
[1] = Event.DateAndTime = "28-7-2015 7:00";
[2] = Event.DateAndTime = "28-7-2015 11:30";
[3] = Event.DateAndTime = "29-7-2015 7:00";
[4] = Event.DateAndTime = "29-7-2015 11:30";
[5] = Event.DateAndTime = "30-7-2015 7:00";
[6] = Event.DateAndTime = "30-7-2015 11:30";
[7] = Event.DateAndTime = "31-7-2015 7:00";
[8] = Event.DateAndTime = "31-7-2015 11:30";
[9] = Event.DateAndTime = "1-8-2015 7:00";