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日等”?您的意思是您正试图从现在开始创建下一个10DateTime
值,其中包含列表中的时间?您所说的“时区”是什么意思“在这儿?我强烈怀疑它可能和我的不一样。如果你能更清楚地说明你真正想要实现的目标,我想可能有更好的方法来实现它。我认为这根本不是排序问题。我已经更新了我的问题,希望这更有意义。“我得到了一个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";